<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Digital Life | Attack on Life</title><link>https://en.1991421.cn/category/digital-life/</link><atom:link href="https://en.1991421.cn/category/digital-life/index.xml" rel="self" type="application/rss+xml"/><description>Digital Life</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-US</language><lastBuildDate>Thu, 09 Apr 2026 17:04:28 +0800</lastBuildDate><image><url>https://en.1991421.cn/media/sharing.png</url><title>Digital Life</title><link>https://en.1991421.cn/category/digital-life/</link></image><item><title>How to Register a Nigeria or Turkey Apple ID to Save on Subscriptions</title><link>https://en.1991421.cn/2026/04/09/how-to-register-apple-id-in-nigeria-turkey/</link><pubDate>Thu, 09 Apr 2026 17:04:28 +0800</pubDate><guid>https://en.1991421.cn/2026/04/09/how-to-register-apple-id-in-nigeria-turkey/</guid><description>&lt;blockquote>
&lt;p>To save on AI subscription costs, I have long used low-price App Store regions such as Turkey or Nigeria. Besides paying with gift cards, another issue is registering the Apple ID itself. A friend recently asked me about this, so I am summarizing the registration methods here.&lt;/p>
&lt;/blockquote>
&lt;p>There are basically two methods.&lt;/p>
&lt;ol>
&lt;li>&lt;code>Directly register&lt;/code> an account for the target country.&lt;/li>
&lt;li>First register an account for &lt;code>your own country&lt;/code>, do nothing else, such as adding balance, and then change the country/region directly.&lt;/li>
&lt;/ol>
&lt;h2 id="register-an-account">
&lt;a class="heading-anchor-link" href="#register-an-account">Register an Account&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="register-an-account"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I will not go through every detail of account registration, because the &lt;a href="https://account.apple.com/account" target="_blank" rel="noopener">official website&lt;/a> is already clear enough. Just follow Apple&amp;rsquo;s steps and fill in the information. One thing to note: when registering an account for a specific country, it is best to have a network environment from that country. For example, when registering a US Apple ID, it is better to use a US IP address. This can avoid unnecessary trouble. If you encounter strange errors during registration, the network may be the reason. For example, I had issues directly registering a Nigeria Apple ID, so I eventually registered with China as the country first, then changed the country to Nigeria after the account was created.&lt;/p>
&lt;h2 id="change-countryregion">
&lt;a class="heading-anchor-link" href="#change-countryregion">Change Country/Region&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="change-countryregion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>The account cannot have a remaining balance. So if this is a new account and you plan to change region, do not add balance during registration. Change the country immediately after registration.&lt;/li>
&lt;li>If you already added balance, you need to use it up or contact Apple Support to clear it.&lt;/li>
&lt;/ol>
&lt;h2 id="apple-id-payment">
&lt;a class="heading-anchor-link" href="#apple-id-payment">Apple ID Payment&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-id-payment"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Since you usually do not have a local payment method for the target country, you need to buy an Apple Gift Card for that country. After redeeming it, you can use the account normally. For my Turkey/Nigeria Apple IDs, I solve this by buying corresponding gift cards. In China, for example, you can buy them through Xianyu.&lt;/li>
&lt;/ol>
&lt;h3 id="turkey-gift-card">
&lt;a class="heading-anchor-link" href="#turkey-gift-card">Turkey Gift Card&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="turkey-gift-card"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>
&lt;div class="tgcs-card">
&lt;div class="tgcs-header">
&lt;div class="tgcs-header-icon">🎁&lt;/div>
&lt;div>
&lt;div class="tgcs-title">Turkish iTunes Gift Card&lt;/div>
&lt;div class="tgcs-subtitle">500 TRY/card · Delivered within 24 hrs · Exchange rate conversion applies — slightly above direct local price&lt;/div>
&lt;/div>
&lt;div class="tgcs-price-tag">USD $14&lt;span>/card&lt;/span>&lt;/div>
&lt;/div>
&lt;div class="tgcs-notice">💡 $14/card · Fixed price · Exchange rate loss included&lt;/div>
&lt;div class="tgcs-body">
&lt;div class="tgcs-qty-row">
&lt;span class="tgcs-label">Quantity&lt;/span>
&lt;div class="tgcs-qty-ctrl">
&lt;button class="tgcs-qty-btn cursor-pointer" id="tgcs-minus">−&lt;/button>
&lt;span id="tgcs-qty-display">2&lt;/span>
&lt;button class="tgcs-qty-btn cursor-pointer" id="tgcs-plus">+&lt;/button>
&lt;/div>
&lt;span class="tgcs-total" id="tgcs-total">Total: USD $28&lt;/span>
&lt;/div>
&lt;div class="tgcs-email-row">
&lt;input
type="email"
id="tgcs-email"
class="tgcs-email-input"
placeholder="Your email (to receive the card code)"
/>
&lt;/div>
&lt;button id="tgcs-buy-btn" class="tgcs-buy-btn cursor-pointer">
Pay with Card
&lt;/button>
&lt;p id="tgcs-msg" class="tgcs-msg" style="display:none">&lt;/p>
&lt;p class="tgcs-note">
After payment, the gift card code will be sent to your email within 24 hours.
&lt;/p>
&lt;details class="payment-faq">
&lt;summary>Payment issues?&lt;/summary>
&lt;div class="payment-faq-body">If you see 'payment blocked' or 'too risky', this is Stripe's automated fraud prevention — not a merchant decision. Common causes and fixes:&lt;br>&lt;br>&lt;strong>1. VPN / Proxy&lt;/strong>&lt;br>Turn off your VPN or switch to a node matching your card's issuing country. IP-to-card country mismatch often triggers the block.&lt;br>&lt;br>&lt;strong>2. Card not enabled for international payments&lt;/strong>&lt;br>Make sure your credit/debit card has international online transactions enabled — some banks disable this by default.&lt;br>&lt;br>&lt;strong>3. Try a different card&lt;/strong>&lt;br>Prefer Visa / Mastercard credit cards. Prepaid or virtual cards are more likely to be blocked.&lt;br>&lt;br>&lt;strong>4. Browser issues&lt;/strong>&lt;br>Try incognito/private mode, or a different browser. Some extensions can interfere with the payment flow.&lt;br>&lt;br>&lt;strong>5. Still not working?&lt;/strong>&lt;br>Contact the author via Alipay or PayPal to complete the payment.&lt;/div>
&lt;/details>
&lt;/div>
&lt;/div>
&lt;script>
(function () {
var qty = 2;
var min = 1;
var max = 5;
var unitPrice = 14;
var btn = document.getElementById('tgcs-buy-btn');
var msg = document.getElementById('tgcs-msg');
function updateDisplay() {
document.getElementById('tgcs-qty-display').textContent = qty;
document.getElementById('tgcs-total').textContent = 'Total: USD $' + (qty * unitPrice);
document.getElementById('tgcs-minus').disabled = qty &lt;= min;
document.getElementById('tgcs-plus').disabled = qty >= max;
}
document.getElementById('tgcs-minus').addEventListener('click', function () {
if (qty > min) { qty--; updateDisplay(); }
});
document.getElementById('tgcs-plus').addEventListener('click', function () {
if (qty &lt; max) { qty++; updateDisplay(); }
});
btn.addEventListener('click', function () {
var email = document.getElementById('tgcs-email').value.trim();
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
msg.style.display = 'block';
msg.className = 'tgcs-msg tgcs-msg-error';
msg.textContent = 'Please enter a valid email address.';
return;
}
btn.disabled = true;
btn.textContent = 'Redirecting...';
msg.style.display = 'none';
fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'turkey_gift_card', quantity: qty, email: email, returnUrl: window.location.href }),
})
.then(function (r) { return r.json(); })
.then(function (data) {
if (data.url) {
window.location.href = data.url;
} else {
msg.style.display = 'block';
msg.className = 'tgcs-msg tgcs-msg-error';
msg.textContent = data.error || 'Something went wrong. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
}
})
.catch(function () {
msg.style.display = 'block';
msg.className = 'tgcs-msg tgcs-msg-error';
msg.textContent = 'Network error. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
});
});
})();
&lt;/script>
&lt;style>
.tgcs-card {
margin: 1.5rem 0;
border-radius: 14px;
border: 1px solid #dbeafe;
background: #fff;
overflow: hidden;
box-shadow: 0 2px 12px rgba(37, 99, 235, 0.08);
}
:root.dark .tgcs-card {
background: #1a2035;
border-color: #1e3a5f;
}
.tgcs-header {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem 1.25rem;
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
color: white;
}
.tgcs-header-icon {
font-size: 1.75rem;
flex-shrink: 0;
}
.tgcs-title {
font-size: 1rem;
font-weight: 700;
}
.tgcs-subtitle {
font-size: 0.8rem;
opacity: 0.85;
margin-top: 2px;
}
.tgcs-price-tag {
margin-left: auto;
font-size: 1.5rem;
font-weight: 800;
white-space: nowrap;
}
.tgcs-price-tag span {
font-size: 0.85rem;
font-weight: 400;
opacity: 0.85;
}
.tgcs-notice {
padding: 0.5rem 1.25rem;
font-size: 0.8rem;
color: #1e40af;
background: #eff6ff;
border-top: 1px solid #bfdbfe;
}
:root.dark .tgcs-notice {
color: #93c5fd;
background: #172554;
border-color: #1e3a8a;
}
.tgcs-body {
padding: 1.25rem;
display: flex;
flex-direction: column;
gap: 0.875rem;
}
.tgcs-qty-row {
display: flex;
align-items: center;
gap: 0.75rem;
}
.tgcs-label {
font-size: 0.9rem;
color: #374151;
font-weight: 500;
}
:root.dark .tgcs-label {
color: #d1d5db;
}
.tgcs-qty-ctrl {
display: flex;
align-items: center;
gap: 0;
border: 1px solid #d1d5db;
border-radius: 8px;
overflow: hidden;
}
:root.dark .tgcs-qty-ctrl {
border-color: #374151;
}
.tgcs-qty-btn {
width: 32px;
height: 32px;
border: none;
background: #f9fafb;
color: #374151;
font-size: 1.1rem;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.15s;
}
:root.dark .tgcs-qty-btn {
background: #374151;
color: #e5e7eb;
}
.tgcs-qty-btn:hover:not(:disabled) {
background: #e5e7eb;
}
:root.dark .tgcs-qty-btn:hover:not(:disabled) {
background: #4b5563;
}
.tgcs-qty-btn:disabled {
opacity: 0.35;
cursor: not-allowed;
}
#tgcs-qty-display {
min-width: 32px;
text-align: center;
font-size: 0.95rem;
font-weight: 600;
color: #111827;
}
:root.dark #tgcs-qty-display {
color: #f9fafb;
}
.tgcs-total {
margin-left: auto;
font-size: 0.95rem;
font-weight: 700;
color: #2563eb;
}
.tgcs-email-row {
display: flex;
}
.tgcs-email-input {
width: 100%;
padding: 0.6rem 0.875rem;
border: 1px solid #d1d5db;
border-radius: 8px;
font-size: 0.9rem;
color: #111827;
background: #fff;
box-sizing: border-box;
transition: border-color 0.2s;
outline: none;
}
:root.dark .tgcs-email-input {
background: #1f2937;
border-color: #374151;
color: #f3f4f6;
}
.tgcs-email-input:focus {
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.tgcs-buy-btn {
width: 100%;
padding: 0.7rem;
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
color: white;
border: none;
border-radius: 8px;
font-size: 0.95rem;
font-weight: 600;
transition: opacity 0.2s, transform 0.15s;
}
.tgcs-buy-btn:hover:not(:disabled) {
opacity: 0.92;
transform: translateY(-1px);
}
.tgcs-buy-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.tgcs-msg {
font-size: 0.85rem;
padding: 0.5rem 0.75rem;
border-radius: 6px;
margin: 0;
}
.tgcs-msg-error {
background: #fef2f2;
color: #dc2626;
}
:root.dark .tgcs-msg-error {
background: #3f1515;
color: #f87171;
}
.tgcs-note {
font-size: 0.8rem;
color: #9ca3af;
margin: 0;
text-align: center;
}
&lt;/style>
&lt;h3 id="nigeria-gift-card">
&lt;a class="heading-anchor-link" href="#nigeria-gift-card">Nigeria Gift Card&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="nigeria-gift-card"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>
&lt;div class="gcs-card">
&lt;div class="gcs-header">
&lt;div class="gcs-header-icon">🎁&lt;/div>
&lt;div>
&lt;div class="gcs-title">Nigerian iTunes Gift Card&lt;/div>
&lt;div class="gcs-subtitle">~14,900–15,000 NGN · Delivered within 24 hrs · Slightly above market price to cover service &amp; transaction fees&lt;/div>
&lt;/div>
&lt;div class="gcs-price-tag" id="gcs-price-tag">USD $--&lt;span>/card&lt;/span>&lt;/div>
&lt;/div>
&lt;div class="gcs-min-notice" id="gcs-min-notice">⚠️ Loading...&lt;/div>
&lt;div class="gcs-body">
&lt;div class="gcs-qty-row">
&lt;span class="gcs-label">Quantity&lt;/span>
&lt;div class="gcs-qty-ctrl">
&lt;button class="gcs-qty-btn cursor-pointer" id="gcs-minus">−&lt;/button>
&lt;span id="gcs-qty-display">1&lt;/span>
&lt;button class="gcs-qty-btn cursor-pointer" id="gcs-plus">+&lt;/button>
&lt;/div>
&lt;span class="gcs-total" id="gcs-total">Total: USD $--&lt;/span>
&lt;/div>
&lt;div class="gcs-email-row">
&lt;input
type="email"
id="gcs-email"
class="gcs-email-input"
placeholder="Your email (to receive the card code)"
/>
&lt;/div>
&lt;button id="gcs-buy-btn" class="gcs-buy-btn cursor-pointer">
Pay with Card
&lt;/button>
&lt;p id="gcs-msg" class="gcs-msg" style="display:none">&lt;/p>
&lt;p class="gcs-note">
After payment, the gift card code will be sent to your email within 24 hours.
&lt;/p>
&lt;details class="payment-faq">
&lt;summary>Payment issues?&lt;/summary>
&lt;div class="payment-faq-body">If you see 'payment blocked' or 'too risky', this is Stripe's automated fraud prevention — not a merchant decision. Common causes and fixes:&lt;br>&lt;br>&lt;strong>1. VPN / Proxy&lt;/strong>&lt;br>Turn off your VPN or switch to a node matching your card's issuing country. IP-to-card country mismatch often triggers the block.&lt;br>&lt;br>&lt;strong>2. Card not enabled for international payments&lt;/strong>&lt;br>Make sure your credit/debit card has international online transactions enabled — some banks disable this by default.&lt;br>&lt;br>&lt;strong>3. Try a different card&lt;/strong>&lt;br>Prefer Visa / Mastercard credit cards. Prepaid or virtual cards are more likely to be blocked.&lt;br>&lt;br>&lt;strong>4. Browser issues&lt;/strong>&lt;br>Try incognito/private mode, or a different browser. Some extensions can interfere with the payment flow.&lt;br>&lt;br>&lt;strong>5. Still not working?&lt;/strong>&lt;br>Contact the author via Alipay or PayPal to complete the payment.&lt;/div>
&lt;/details>
&lt;/div>
&lt;/div>
&lt;script>
(function () {
var qty = 0;
var min = 0;
var max = 0;
var pricing = [];
var configLoaded = false;
var btn = document.getElementById('gcs-buy-btn');
var msg = document.getElementById('gcs-msg');
btn.disabled = true;
function getUnitPrice(q, p) {
var tier = p.find(function (t) { return q >= t.minQty &amp;&amp; q &lt;= t.maxQty; });
return tier ? tier.price : p[p.length - 1].price;
}
function updateDisplay() {
var unitPrice = getUnitPrice(qty, pricing);
document.getElementById('gcs-qty-display').textContent = qty;
document.getElementById('gcs-total').textContent = 'Total: USD $' + (qty * unitPrice);
document.getElementById('gcs-price-tag').innerHTML = 'USD $' + unitPrice + '&lt;span>/card&lt;/span>';
document.getElementById('gcs-minus').disabled = qty &lt;= min;
document.getElementById('gcs-plus').disabled = qty >= max;
}
fetch('/api/nigeria-gift-card-config')
.then(function (r) { return r.json(); })
.then(function (cfg) {
pricing = cfg.pricing;
min = cfg.min;
max = cfg.max;
qty = cfg.defaultQty || cfg.min;
configLoaded = true;
document.getElementById('gcs-min-notice').textContent =
'💡 USD $16/card. Recommended: 2 cards.';
btn.disabled = false;
updateDisplay();
})
.catch(function () {
msg.style.display = 'block';
msg.className = 'gcs-msg gcs-msg-error';
msg.textContent = 'Failed to load pricing. Please refresh the page.';
document.getElementById('gcs-min-notice').textContent = '⚠️ Failed to load configuration.';
});
document.getElementById('gcs-minus').addEventListener('click', function () {
if (configLoaded &amp;&amp; qty > min) { qty--; updateDisplay(); }
});
document.getElementById('gcs-plus').addEventListener('click', function () {
if (configLoaded &amp;&amp; qty &lt; max) { qty++; updateDisplay(); }
});
btn.addEventListener('click', function () {
if (!configLoaded) return;
var email = document.getElementById('gcs-email').value.trim();
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
msg.style.display = 'block';
msg.className = 'gcs-msg gcs-msg-error';
msg.textContent = 'Please enter a valid email address.';
return;
}
btn.disabled = true;
btn.textContent = 'Redirecting...';
msg.style.display = 'none';
fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'gift_card', quantity: qty, email: email, returnUrl: window.location.href }),
})
.then(function (r) { return r.json(); })
.then(function (data) {
if (data.url) {
window.location.href = data.url;
} else {
msg.style.display = 'block';
msg.className = 'gcs-msg gcs-msg-error';
msg.textContent = data.error || 'Something went wrong. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
}
})
.catch(function () {
msg.style.display = 'block';
msg.className = 'gcs-msg gcs-msg-error';
msg.textContent = 'Network error. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
});
});
})();
&lt;/script>
&lt;style>
.gcs-card {
margin: 1.5rem 0;
border-radius: 14px;
border: 1px solid #d1fae5;
background: #fff;
overflow: hidden;
box-shadow: 0 2px 12px rgba(5, 150, 105, 0.08);
}
:root.dark .gcs-card {
background: #1a2e25;
border-color: #064e3b;
}
.gcs-header {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem 1.25rem;
background: linear-gradient(135deg, #059669 0%, #0d9488 100%);
color: white;
}
.gcs-header-icon {
font-size: 1.75rem;
flex-shrink: 0;
}
.gcs-title {
font-size: 1rem;
font-weight: 700;
}
.gcs-subtitle {
font-size: 0.8rem;
opacity: 0.85;
margin-top: 2px;
}
.gcs-price-tag {
margin-left: auto;
font-size: 1.5rem;
font-weight: 800;
white-space: nowrap;
}
.gcs-price-tag span {
font-size: 0.85rem;
font-weight: 400;
opacity: 0.85;
}
.gcs-body {
padding: 1.25rem;
display: flex;
flex-direction: column;
gap: 0.875rem;
}
.gcs-qty-row {
display: flex;
align-items: center;
gap: 0.75rem;
}
.gcs-label {
font-size: 0.9rem;
color: #374151;
font-weight: 500;
}
:root.dark .gcs-label {
color: #d1d5db;
}
.gcs-qty-ctrl {
display: flex;
align-items: center;
gap: 0;
border: 1px solid #d1d5db;
border-radius: 8px;
overflow: hidden;
}
:root.dark .gcs-qty-ctrl {
border-color: #374151;
}
.gcs-qty-btn {
width: 32px;
height: 32px;
border: none;
background: #f9fafb;
color: #374151;
font-size: 1.1rem;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.15s;
}
:root.dark .gcs-qty-btn {
background: #374151;
color: #e5e7eb;
}
.gcs-qty-btn:hover:not(:disabled) {
background: #e5e7eb;
}
:root.dark .gcs-qty-btn:hover:not(:disabled) {
background: #4b5563;
}
.gcs-qty-btn:disabled {
opacity: 0.35;
cursor: not-allowed;
}
#gcs-qty-display {
min-width: 32px;
text-align: center;
font-size: 0.95rem;
font-weight: 600;
color: #111827;
}
:root.dark #gcs-qty-display {
color: #f9fafb;
}
.gcs-total {
margin-left: auto;
font-size: 0.95rem;
font-weight: 700;
color: #059669;
}
.gcs-email-input {
width: 100%;
padding: 0.6rem 0.875rem;
border: 1px solid #d1d5db;
border-radius: 8px;
font-size: 0.9rem;
color: #111827;
background: #fff;
box-sizing: border-box;
transition: border-color 0.2s;
outline: none;
}
:root.dark .gcs-email-input {
background: #1f2937;
border-color: #374151;
color: #f3f4f6;
}
.gcs-email-input:focus {
border-color: #059669;
box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.12);
}
.gcs-buy-btn {
width: 100%;
padding: 0.7rem;
background: linear-gradient(135deg, #059669 0%, #0d9488 100%);
color: white;
border: none;
border-radius: 8px;
font-size: 0.95rem;
font-weight: 600;
transition: opacity 0.2s, transform 0.15s;
}
.gcs-buy-btn:hover:not(:disabled) {
opacity: 0.92;
transform: translateY(-1px);
}
.gcs-buy-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.gcs-msg {
font-size: 0.85rem;
padding: 0.5rem 0.75rem;
border-radius: 6px;
margin: 0;
}
.gcs-msg-error {
background: #fef2f2;
color: #dc2626;
}
:root.dark .gcs-msg-error {
background: #3f1515;
color: #f87171;
}
.gcs-note {
font-size: 0.8rem;
color: #9ca3af;
margin: 0;
text-align: center;
}
.gcs-note a {
color: #059669;
}
.gcs-min-notice {
padding: 0.5rem 1.25rem;
font-size: 0.8rem;
color: #92400e;
background: #fef3c7;
border-top: 1px solid #fde68a;
}
:root.dark .gcs-min-notice {
color: #fcd34d;
background: #422006;
border-color: #713f12;
}
&lt;/style>
&lt;h2 id="do-not-frequently-lend-the-account-to-others">
&lt;a class="heading-anchor-link" href="#do-not-frequently-lend-the-account-to-others">Do Not Frequently Lend the Account to Others&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="do-not-frequently-lend-the-account-to-others"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Apple IDs also have risk controls. If the account frequently logs into different devices, or you lend it to others too often, Apple may consider it abnormal behavior and ban the account. If you already have subscriptions or purchased apps, that would cause losses. So pay attention to account usage frequency and avoid lending it out frequently, especially for accounts in different countries.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In short, I hope you can use the advantages of multi-region Apple IDs and regional pricing to reasonably register and use Apple IDs from different countries, saving on subscription fees and app purchases. It also gives you more app freedom, since some apps are only available in specific countries&amp;rsquo; App Stores.&lt;/p></description></item><item><title>How to Register an Apple ID in Nigeria or Turkey</title><link>https://en.1991421.cn/2026/04/09/how-to-register-apple-id-in-nigeria-turkey/</link><pubDate>Thu, 09 Apr 2026 17:04:28 +0800</pubDate><guid>https://en.1991421.cn/2026/04/09/how-to-register-apple-id-in-nigeria-turkey/</guid><description>&lt;blockquote>
&lt;p>To save on AI subscription costs, I&amp;rsquo;ve been using low-price region App Store subscriptions in Turkey or Nigeria. Besides the payment issue (solved via gift cards), another common question is how to register an Apple ID for these regions. A friend asked me recently, so here&amp;rsquo;s a summary:&lt;/p>
&lt;/blockquote>
&lt;p>There are two approaches:&lt;/p>
&lt;ol>
&lt;li>&lt;code>Register directly&lt;/code> in the target country.&lt;/li>
&lt;li>Register with &lt;code>your own country&lt;/code> first — don&amp;rsquo;t do anything else like topping up — then change the country/region immediately.&lt;/li>
&lt;/ol>
&lt;h2 id="registering-an-account">
&lt;a class="heading-anchor-link" href="#registering-an-account">Registering an Account&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="registering-an-account"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I won&amp;rsquo;t go into every detail of account registration since &lt;a href="https://account.apple.com/account" target="_blank" rel="noopener">Apple&amp;rsquo;s official page&lt;/a> is clear enough — just follow the steps there. One thing to note: when registering for a specific country, it&amp;rsquo;s best to have a matching network environment. For example, if you&amp;rsquo;re registering a US Apple ID, a US IP address helps avoid unnecessary issues. If you encounter strange errors during registration, it&amp;rsquo;s likely a network issue. When I tried to register a Nigeria Apple ID directly, I ran into problems. My solution was to register with China selected, and after success, switch the country to Nigeria.&lt;/p>
&lt;h2 id="changing-countryregion">
&lt;a class="heading-anchor-link" href="#changing-countryregion">Changing Country/Region&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="changing-countryregion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Your account must have no balance. If you have a new account and plan to switch regions, don&amp;rsquo;t top it up — just register and change the country right away.&lt;/li>
&lt;li>If you&amp;rsquo;ve already topped up, spend the balance first, or contact Apple Support to clear it to zero.&lt;/li>
&lt;/ol>
&lt;h2 id="payment-for-apple-id">
&lt;a class="heading-anchor-link" href="#payment-for-apple-id">Payment for Apple ID&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="payment-for-apple-id"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since you won&amp;rsquo;t have a local payment method for the target country&amp;rsquo;s Apple ID, you&amp;rsquo;ll need to buy that country&amp;rsquo;s Apple Gift Card. Once redeemed, you can use the App Store normally. For my Turkey and Nigeria Apple IDs, I resolve this by purchasing the corresponding gift cards — in China, you can find them on Xianyu (闲鱼).&lt;/p>
&lt;h3 id="turkey-gift-card">
&lt;a class="heading-anchor-link" href="#turkey-gift-card">Turkey Gift Card&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="turkey-gift-card"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>
&lt;div class="tgcs-card">
&lt;div class="tgcs-header">
&lt;div class="tgcs-header-icon">🎁&lt;/div>
&lt;div>
&lt;div class="tgcs-title">Turkish iTunes Gift Card&lt;/div>
&lt;div class="tgcs-subtitle">500 TRY/card · Delivered within 24 hrs · Exchange rate conversion applies — slightly above direct local price&lt;/div>
&lt;/div>
&lt;div class="tgcs-price-tag">USD $14&lt;span>/card&lt;/span>&lt;/div>
&lt;/div>
&lt;div class="tgcs-notice">💡 $14/card · Fixed price · Exchange rate loss included&lt;/div>
&lt;div class="tgcs-body">
&lt;div class="tgcs-qty-row">
&lt;span class="tgcs-label">Quantity&lt;/span>
&lt;div class="tgcs-qty-ctrl">
&lt;button class="tgcs-qty-btn cursor-pointer" id="tgcs-minus">−&lt;/button>
&lt;span id="tgcs-qty-display">2&lt;/span>
&lt;button class="tgcs-qty-btn cursor-pointer" id="tgcs-plus">+&lt;/button>
&lt;/div>
&lt;span class="tgcs-total" id="tgcs-total">Total: USD $28&lt;/span>
&lt;/div>
&lt;div class="tgcs-email-row">
&lt;input
type="email"
id="tgcs-email"
class="tgcs-email-input"
placeholder="Your email (to receive the card code)"
/>
&lt;/div>
&lt;button id="tgcs-buy-btn" class="tgcs-buy-btn cursor-pointer">
Pay with Card
&lt;/button>
&lt;p id="tgcs-msg" class="tgcs-msg" style="display:none">&lt;/p>
&lt;p class="tgcs-note">
After payment, the gift card code will be sent to your email within 24 hours.
&lt;/p>
&lt;details class="payment-faq">
&lt;summary>Payment issues?&lt;/summary>
&lt;div class="payment-faq-body">If you see 'payment blocked' or 'too risky', this is Stripe's automated fraud prevention — not a merchant decision. Common causes and fixes:&lt;br>&lt;br>&lt;strong>1. VPN / Proxy&lt;/strong>&lt;br>Turn off your VPN or switch to a node matching your card's issuing country. IP-to-card country mismatch often triggers the block.&lt;br>&lt;br>&lt;strong>2. Card not enabled for international payments&lt;/strong>&lt;br>Make sure your credit/debit card has international online transactions enabled — some banks disable this by default.&lt;br>&lt;br>&lt;strong>3. Try a different card&lt;/strong>&lt;br>Prefer Visa / Mastercard credit cards. Prepaid or virtual cards are more likely to be blocked.&lt;br>&lt;br>&lt;strong>4. Browser issues&lt;/strong>&lt;br>Try incognito/private mode, or a different browser. Some extensions can interfere with the payment flow.&lt;br>&lt;br>&lt;strong>5. Still not working?&lt;/strong>&lt;br>Contact the author via Alipay or PayPal to complete the payment.&lt;/div>
&lt;/details>
&lt;/div>
&lt;/div>
&lt;script>
(function () {
var qty = 2;
var min = 1;
var max = 5;
var unitPrice = 14;
var btn = document.getElementById('tgcs-buy-btn');
var msg = document.getElementById('tgcs-msg');
function updateDisplay() {
document.getElementById('tgcs-qty-display').textContent = qty;
document.getElementById('tgcs-total').textContent = 'Total: USD $' + (qty * unitPrice);
document.getElementById('tgcs-minus').disabled = qty &lt;= min;
document.getElementById('tgcs-plus').disabled = qty >= max;
}
document.getElementById('tgcs-minus').addEventListener('click', function () {
if (qty > min) { qty--; updateDisplay(); }
});
document.getElementById('tgcs-plus').addEventListener('click', function () {
if (qty &lt; max) { qty++; updateDisplay(); }
});
btn.addEventListener('click', function () {
var email = document.getElementById('tgcs-email').value.trim();
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
msg.style.display = 'block';
msg.className = 'tgcs-msg tgcs-msg-error';
msg.textContent = 'Please enter a valid email address.';
return;
}
btn.disabled = true;
btn.textContent = 'Redirecting...';
msg.style.display = 'none';
fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'turkey_gift_card', quantity: qty, email: email, returnUrl: window.location.href }),
})
.then(function (r) { return r.json(); })
.then(function (data) {
if (data.url) {
window.location.href = data.url;
} else {
msg.style.display = 'block';
msg.className = 'tgcs-msg tgcs-msg-error';
msg.textContent = data.error || 'Something went wrong. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
}
})
.catch(function () {
msg.style.display = 'block';
msg.className = 'tgcs-msg tgcs-msg-error';
msg.textContent = 'Network error. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
});
});
})();
&lt;/script>
&lt;style>
.tgcs-card {
margin: 1.5rem 0;
border-radius: 14px;
border: 1px solid #dbeafe;
background: #fff;
overflow: hidden;
box-shadow: 0 2px 12px rgba(37, 99, 235, 0.08);
}
:root.dark .tgcs-card {
background: #1a2035;
border-color: #1e3a5f;
}
.tgcs-header {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem 1.25rem;
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
color: white;
}
.tgcs-header-icon {
font-size: 1.75rem;
flex-shrink: 0;
}
.tgcs-title {
font-size: 1rem;
font-weight: 700;
}
.tgcs-subtitle {
font-size: 0.8rem;
opacity: 0.85;
margin-top: 2px;
}
.tgcs-price-tag {
margin-left: auto;
font-size: 1.5rem;
font-weight: 800;
white-space: nowrap;
}
.tgcs-price-tag span {
font-size: 0.85rem;
font-weight: 400;
opacity: 0.85;
}
.tgcs-notice {
padding: 0.5rem 1.25rem;
font-size: 0.8rem;
color: #1e40af;
background: #eff6ff;
border-top: 1px solid #bfdbfe;
}
:root.dark .tgcs-notice {
color: #93c5fd;
background: #172554;
border-color: #1e3a8a;
}
.tgcs-body {
padding: 1.25rem;
display: flex;
flex-direction: column;
gap: 0.875rem;
}
.tgcs-qty-row {
display: flex;
align-items: center;
gap: 0.75rem;
}
.tgcs-label {
font-size: 0.9rem;
color: #374151;
font-weight: 500;
}
:root.dark .tgcs-label {
color: #d1d5db;
}
.tgcs-qty-ctrl {
display: flex;
align-items: center;
gap: 0;
border: 1px solid #d1d5db;
border-radius: 8px;
overflow: hidden;
}
:root.dark .tgcs-qty-ctrl {
border-color: #374151;
}
.tgcs-qty-btn {
width: 32px;
height: 32px;
border: none;
background: #f9fafb;
color: #374151;
font-size: 1.1rem;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.15s;
}
:root.dark .tgcs-qty-btn {
background: #374151;
color: #e5e7eb;
}
.tgcs-qty-btn:hover:not(:disabled) {
background: #e5e7eb;
}
:root.dark .tgcs-qty-btn:hover:not(:disabled) {
background: #4b5563;
}
.tgcs-qty-btn:disabled {
opacity: 0.35;
cursor: not-allowed;
}
#tgcs-qty-display {
min-width: 32px;
text-align: center;
font-size: 0.95rem;
font-weight: 600;
color: #111827;
}
:root.dark #tgcs-qty-display {
color: #f9fafb;
}
.tgcs-total {
margin-left: auto;
font-size: 0.95rem;
font-weight: 700;
color: #2563eb;
}
.tgcs-email-row {
display: flex;
}
.tgcs-email-input {
width: 100%;
padding: 0.6rem 0.875rem;
border: 1px solid #d1d5db;
border-radius: 8px;
font-size: 0.9rem;
color: #111827;
background: #fff;
box-sizing: border-box;
transition: border-color 0.2s;
outline: none;
}
:root.dark .tgcs-email-input {
background: #1f2937;
border-color: #374151;
color: #f3f4f6;
}
.tgcs-email-input:focus {
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.tgcs-buy-btn {
width: 100%;
padding: 0.7rem;
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
color: white;
border: none;
border-radius: 8px;
font-size: 0.95rem;
font-weight: 600;
transition: opacity 0.2s, transform 0.15s;
}
.tgcs-buy-btn:hover:not(:disabled) {
opacity: 0.92;
transform: translateY(-1px);
}
.tgcs-buy-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.tgcs-msg {
font-size: 0.85rem;
padding: 0.5rem 0.75rem;
border-radius: 6px;
margin: 0;
}
.tgcs-msg-error {
background: #fef2f2;
color: #dc2626;
}
:root.dark .tgcs-msg-error {
background: #3f1515;
color: #f87171;
}
.tgcs-note {
font-size: 0.8rem;
color: #9ca3af;
margin: 0;
text-align: center;
}
&lt;/style>
&lt;h3 id="nigeria-gift-card">
&lt;a class="heading-anchor-link" href="#nigeria-gift-card">Nigeria Gift Card&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="nigeria-gift-card"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>
&lt;div class="gcs-card">
&lt;div class="gcs-header">
&lt;div class="gcs-header-icon">🎁&lt;/div>
&lt;div>
&lt;div class="gcs-title">Nigerian iTunes Gift Card&lt;/div>
&lt;div class="gcs-subtitle">~14,900–15,000 NGN · Delivered within 24 hrs · Slightly above market price to cover service &amp; transaction fees&lt;/div>
&lt;/div>
&lt;div class="gcs-price-tag" id="gcs-price-tag">USD $--&lt;span>/card&lt;/span>&lt;/div>
&lt;/div>
&lt;div class="gcs-min-notice" id="gcs-min-notice">⚠️ Loading...&lt;/div>
&lt;div class="gcs-body">
&lt;div class="gcs-qty-row">
&lt;span class="gcs-label">Quantity&lt;/span>
&lt;div class="gcs-qty-ctrl">
&lt;button class="gcs-qty-btn cursor-pointer" id="gcs-minus">−&lt;/button>
&lt;span id="gcs-qty-display">1&lt;/span>
&lt;button class="gcs-qty-btn cursor-pointer" id="gcs-plus">+&lt;/button>
&lt;/div>
&lt;span class="gcs-total" id="gcs-total">Total: USD $--&lt;/span>
&lt;/div>
&lt;div class="gcs-email-row">
&lt;input
type="email"
id="gcs-email"
class="gcs-email-input"
placeholder="Your email (to receive the card code)"
/>
&lt;/div>
&lt;button id="gcs-buy-btn" class="gcs-buy-btn cursor-pointer">
Pay with Card
&lt;/button>
&lt;p id="gcs-msg" class="gcs-msg" style="display:none">&lt;/p>
&lt;p class="gcs-note">
After payment, the gift card code will be sent to your email within 24 hours.
&lt;/p>
&lt;details class="payment-faq">
&lt;summary>Payment issues?&lt;/summary>
&lt;div class="payment-faq-body">If you see 'payment blocked' or 'too risky', this is Stripe's automated fraud prevention — not a merchant decision. Common causes and fixes:&lt;br>&lt;br>&lt;strong>1. VPN / Proxy&lt;/strong>&lt;br>Turn off your VPN or switch to a node matching your card's issuing country. IP-to-card country mismatch often triggers the block.&lt;br>&lt;br>&lt;strong>2. Card not enabled for international payments&lt;/strong>&lt;br>Make sure your credit/debit card has international online transactions enabled — some banks disable this by default.&lt;br>&lt;br>&lt;strong>3. Try a different card&lt;/strong>&lt;br>Prefer Visa / Mastercard credit cards. Prepaid or virtual cards are more likely to be blocked.&lt;br>&lt;br>&lt;strong>4. Browser issues&lt;/strong>&lt;br>Try incognito/private mode, or a different browser. Some extensions can interfere with the payment flow.&lt;br>&lt;br>&lt;strong>5. Still not working?&lt;/strong>&lt;br>Contact the author via Alipay or PayPal to complete the payment.&lt;/div>
&lt;/details>
&lt;/div>
&lt;/div>
&lt;script>
(function () {
var qty = 0;
var min = 0;
var max = 0;
var pricing = [];
var configLoaded = false;
var btn = document.getElementById('gcs-buy-btn');
var msg = document.getElementById('gcs-msg');
btn.disabled = true;
function getUnitPrice(q, p) {
var tier = p.find(function (t) { return q >= t.minQty &amp;&amp; q &lt;= t.maxQty; });
return tier ? tier.price : p[p.length - 1].price;
}
function updateDisplay() {
var unitPrice = getUnitPrice(qty, pricing);
document.getElementById('gcs-qty-display').textContent = qty;
document.getElementById('gcs-total').textContent = 'Total: USD $' + (qty * unitPrice);
document.getElementById('gcs-price-tag').innerHTML = 'USD $' + unitPrice + '&lt;span>/card&lt;/span>';
document.getElementById('gcs-minus').disabled = qty &lt;= min;
document.getElementById('gcs-plus').disabled = qty >= max;
}
fetch('/api/nigeria-gift-card-config')
.then(function (r) { return r.json(); })
.then(function (cfg) {
pricing = cfg.pricing;
min = cfg.min;
max = cfg.max;
qty = cfg.defaultQty || cfg.min;
configLoaded = true;
document.getElementById('gcs-min-notice').textContent =
'💡 USD $16/card. Recommended: 2 cards.';
btn.disabled = false;
updateDisplay();
})
.catch(function () {
msg.style.display = 'block';
msg.className = 'gcs-msg gcs-msg-error';
msg.textContent = 'Failed to load pricing. Please refresh the page.';
document.getElementById('gcs-min-notice').textContent = '⚠️ Failed to load configuration.';
});
document.getElementById('gcs-minus').addEventListener('click', function () {
if (configLoaded &amp;&amp; qty > min) { qty--; updateDisplay(); }
});
document.getElementById('gcs-plus').addEventListener('click', function () {
if (configLoaded &amp;&amp; qty &lt; max) { qty++; updateDisplay(); }
});
btn.addEventListener('click', function () {
if (!configLoaded) return;
var email = document.getElementById('gcs-email').value.trim();
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
msg.style.display = 'block';
msg.className = 'gcs-msg gcs-msg-error';
msg.textContent = 'Please enter a valid email address.';
return;
}
btn.disabled = true;
btn.textContent = 'Redirecting...';
msg.style.display = 'none';
fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'gift_card', quantity: qty, email: email, returnUrl: window.location.href }),
})
.then(function (r) { return r.json(); })
.then(function (data) {
if (data.url) {
window.location.href = data.url;
} else {
msg.style.display = 'block';
msg.className = 'gcs-msg gcs-msg-error';
msg.textContent = data.error || 'Something went wrong. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
}
})
.catch(function () {
msg.style.display = 'block';
msg.className = 'gcs-msg gcs-msg-error';
msg.textContent = 'Network error. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
});
});
})();
&lt;/script>
&lt;style>
.gcs-card {
margin: 1.5rem 0;
border-radius: 14px;
border: 1px solid #d1fae5;
background: #fff;
overflow: hidden;
box-shadow: 0 2px 12px rgba(5, 150, 105, 0.08);
}
:root.dark .gcs-card {
background: #1a2e25;
border-color: #064e3b;
}
.gcs-header {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem 1.25rem;
background: linear-gradient(135deg, #059669 0%, #0d9488 100%);
color: white;
}
.gcs-header-icon {
font-size: 1.75rem;
flex-shrink: 0;
}
.gcs-title {
font-size: 1rem;
font-weight: 700;
}
.gcs-subtitle {
font-size: 0.8rem;
opacity: 0.85;
margin-top: 2px;
}
.gcs-price-tag {
margin-left: auto;
font-size: 1.5rem;
font-weight: 800;
white-space: nowrap;
}
.gcs-price-tag span {
font-size: 0.85rem;
font-weight: 400;
opacity: 0.85;
}
.gcs-body {
padding: 1.25rem;
display: flex;
flex-direction: column;
gap: 0.875rem;
}
.gcs-qty-row {
display: flex;
align-items: center;
gap: 0.75rem;
}
.gcs-label {
font-size: 0.9rem;
color: #374151;
font-weight: 500;
}
:root.dark .gcs-label {
color: #d1d5db;
}
.gcs-qty-ctrl {
display: flex;
align-items: center;
gap: 0;
border: 1px solid #d1d5db;
border-radius: 8px;
overflow: hidden;
}
:root.dark .gcs-qty-ctrl {
border-color: #374151;
}
.gcs-qty-btn {
width: 32px;
height: 32px;
border: none;
background: #f9fafb;
color: #374151;
font-size: 1.1rem;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.15s;
}
:root.dark .gcs-qty-btn {
background: #374151;
color: #e5e7eb;
}
.gcs-qty-btn:hover:not(:disabled) {
background: #e5e7eb;
}
:root.dark .gcs-qty-btn:hover:not(:disabled) {
background: #4b5563;
}
.gcs-qty-btn:disabled {
opacity: 0.35;
cursor: not-allowed;
}
#gcs-qty-display {
min-width: 32px;
text-align: center;
font-size: 0.95rem;
font-weight: 600;
color: #111827;
}
:root.dark #gcs-qty-display {
color: #f9fafb;
}
.gcs-total {
margin-left: auto;
font-size: 0.95rem;
font-weight: 700;
color: #059669;
}
.gcs-email-input {
width: 100%;
padding: 0.6rem 0.875rem;
border: 1px solid #d1d5db;
border-radius: 8px;
font-size: 0.9rem;
color: #111827;
background: #fff;
box-sizing: border-box;
transition: border-color 0.2s;
outline: none;
}
:root.dark .gcs-email-input {
background: #1f2937;
border-color: #374151;
color: #f3f4f6;
}
.gcs-email-input:focus {
border-color: #059669;
box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.12);
}
.gcs-buy-btn {
width: 100%;
padding: 0.7rem;
background: linear-gradient(135deg, #059669 0%, #0d9488 100%);
color: white;
border: none;
border-radius: 8px;
font-size: 0.95rem;
font-weight: 600;
transition: opacity 0.2s, transform 0.15s;
}
.gcs-buy-btn:hover:not(:disabled) {
opacity: 0.92;
transform: translateY(-1px);
}
.gcs-buy-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.gcs-msg {
font-size: 0.85rem;
padding: 0.5rem 0.75rem;
border-radius: 6px;
margin: 0;
}
.gcs-msg-error {
background: #fef2f2;
color: #dc2626;
}
:root.dark .gcs-msg-error {
background: #3f1515;
color: #f87171;
}
.gcs-note {
font-size: 0.8rem;
color: #9ca3af;
margin: 0;
text-align: center;
}
.gcs-note a {
color: #059669;
}
.gcs-min-notice {
padding: 0.5rem 1.25rem;
font-size: 0.8rem;
color: #92400e;
background: #fef3c7;
border-top: 1px solid #fde68a;
}
:root.dark .gcs-min-notice {
color: #fcd34d;
background: #422006;
border-color: #713f12;
}
&lt;/style>
&lt;h2 id="dont-lend-your-account-frequently">
&lt;a class="heading-anchor-link" href="#dont-lend-your-account-frequently">Don&amp;rsquo;t Lend Your Account Frequently&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="dont-lend-your-account-frequently"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Apple IDs can be banned. If your account logs into many different devices or is frequently lent to others, Apple may flag it as abnormal activity and suspend it. Any subscriptions or app purchases would then be lost. Be mindful of your account usage — especially cross-region accounts — and avoid sharing them frequently.&lt;/p>
&lt;h2 id="wrapping-up">
&lt;a class="heading-anchor-link" href="#wrapping-up">Wrapping Up&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wrapping-up"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Hopefully this helps you take advantage of Apple ID&amp;rsquo;s multi-region pricing to reduce subscription and app purchase costs, while also gaining access to apps only available in specific countries&amp;rsquo; App Stores.&lt;/p></description></item><item><title>Side Hustle Guide: Earning Money Through Cloud Storage Promotion</title><link>https://en.1991421.cn/2026/03/14/xianyu-side-hustle-guide-to-earn-money-by-promoting-cloud-storage/</link><pubDate>Sat, 14 Mar 2026 21:25:13 +0800</pubDate><guid>https://en.1991421.cn/2026/03/14/xianyu-side-hustle-guide-to-earn-money-by-promoting-cloud-storage/</guid><description>&lt;blockquote>
&lt;p>I&amp;rsquo;ve long seen many people sharing cloud storage content and was curious about how they made money. Until one day, someone contacted me through my WeChat official account wanting to collaborate on cloud storage promotion. After getting involved, I discovered how it works. The key insight is that this partnership doesn&amp;rsquo;t interfere with how you normally share content. For example, cloud storage links—the address stays exactly the same. When others register for cloud storage, save files, activate VIP memberships, etc., you earn a commission. Why not take advantage of it? Here I&amp;rsquo;ll share the mechanics and insider tips.&lt;/p>
&lt;/blockquote>
&lt;h2 id="recommended-cloud-storage-promotion-partners">
&lt;a class="heading-anchor-link" href="#recommended-cloud-storage-promotion-partners">Recommended Cloud Storage Promotion Partners&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="recommended-cloud-storage-promotion-partners"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>First, here are some reliable cloud storage promotion partners I know of. Of course, there may be others in the market worth exploring.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Cloud Drive Promoter (what I use)&lt;/p>
&lt;ul>
&lt;li>Quark Cloud Drive Influencer Registration Form: &lt;a href="https://docs.qq.com/form/page/DV3lVU2dCYUl4U0dz" target="_blank" rel="noopener">https://docs.qq.com/form/page/DV3lVU2dCYUl4U0dz&lt;/a>&lt;/li>
&lt;li>Baidu Cloud Drive New User and File Transfer VIP Activity Cooperation Details: &lt;a href="https://docs.qq.com/doc/DYktEWVRCWk1xT0J0" target="_blank" rel="noopener">https://docs.qq.com/doc/DYktEWVRCWk1xT0J0&lt;/a>&lt;/li>
&lt;li>There are other cloud services, but I chose these two since I use them regularly and am familiar with them. For inquiries, you can add the partner&amp;rsquo;s WeChat customer service: &lt;code>bust1332978205&lt;/code>&lt;/li>
&lt;li>The mini program I use regularly is &amp;ldquo;Cloud Drive Promoter Statistics Assistant&amp;rdquo;—it&amp;rsquo;s feature-rich with clear data. Highly recommended.&lt;/li>
&lt;li>Cloud Drive Promoter handles withdrawals directly to Alipay with one click, which is very convenient. Earnings settle weekly, usually Friday or Saturday for the previous week&amp;rsquo;s revenue.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/03/2026-03-14-214836.png"
alt="https://static.1991421.cn/2026/03/2026-03-14-214836.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>AchisoLink&lt;/p>
&lt;ul>
&lt;li>I haven&amp;rsquo;t used it personally, but it&amp;rsquo;s fundamentally similar. I use AchisoLink mainly for their auto-delivery feature, and their official customer service is very professional and responsive, which left a good impression. I haven&amp;rsquo;t done a detailed price and benefit comparison, but I understand these services are mature and shouldn&amp;rsquo;t differ significantly.&lt;/li>
&lt;li>One limitation of AchisoLink is that it only supports Quark Cloud Drive. If you only need Quark and are already using AchisoLink&amp;rsquo;s other products like auto-delivery, it could be worth considering.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="which-cloud-drive-activities-generate-revenue">
&lt;a class="heading-anchor-link" href="#which-cloud-drive-activities-generate-revenue">Which Cloud Drive Activities Generate Revenue&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="which-cloud-drive-activities-generate-revenue"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here I&amp;rsquo;ll use Cloud Drive Promoter as an example since it supports multiple cloud drives. As you can see from the screenshot, new sign-ups, VIP activation, and file transfers all generate income.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/03/2026-03-14-213609.jpeg"
alt="https://static.1991421.cn/2026/03/2026-03-14-213609.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="how-revenue-gets-attributed-to-you">
&lt;a class="heading-anchor-link" href="#how-revenue-gets-attributed-to-you">How Revenue Gets Attributed to You&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-revenue-gets-attributed-to-you"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Regardless of which cloud drive you use, you simply provide your cloud drive ID to the partner. Then you continue sharing cloud drive content normally—the address stays exactly the same. There are no added parameters or changed links. Your shared content doesn&amp;rsquo;t change at all, and users won&amp;rsquo;t notice any difference. When users register a cloud drive account, activate VIP memberships, etc., these actions are tracked by the partner and attributed to your ID based on your promotion, crediting you the commission.&lt;/p>
&lt;p>So now you understand—this costs nothing. The only &amp;ldquo;cost&amp;rdquo; is submitting the partnership form.&lt;/p>
&lt;h2 id="showing-my-earnings">
&lt;a class="heading-anchor-link" href="#showing-my-earnings">Showing My Earnings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="showing-my-earnings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I&amp;rsquo;ll share my results here, though I&amp;rsquo;m not a power user. As I mentioned above, this has zero cost, so why not earn some extra money on the side? I continue using cloud drives the same way I always have.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/03/2026-03-14-213818.jpeg"
alt="https://static.1991421.cn/2026/03/2026-03-14-213818.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="quark-cloud-drive--baidu-cloud-drive">
&lt;a class="heading-anchor-link" href="#quark-cloud-drive--baidu-cloud-drive">Quark Cloud Drive / Baidu Cloud Drive&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="quark-cloud-drive--baidu-cloud-drive"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since I use Xianyu (the flea market app) quite a bit, from experience, these are the two cloud drives users rely on most. So if your time is limited, I recommend applying for promotion of just these two.&lt;/p>
&lt;h2 id="quark-cloud-drive-vip">
&lt;a class="heading-anchor-link" href="#quark-cloud-drive-vip">Quark Cloud Drive VIP?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="quark-cloud-drive-vip"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since we&amp;rsquo;re talking about cloud storage promotion, naturally you&amp;rsquo;ll want as much storage space as possible—otherwise how do you store and share massive resources?&lt;/p>
&lt;p>Free storage is very limited. You could purchase VIP separately, but if you want to save money, I personally recommend getting 88 VIP instead, which includes Quark Cloud Drive VIP with &lt;code>6TB of storage&lt;/code>—more than enough for me.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/03/2026-03-18-221504.jpeg"
alt="https://static.1991421.cn/2026/03/2026-03-18-221504.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="baidu-cloud-drive-vip">
&lt;a class="heading-anchor-link" href="#baidu-cloud-drive-vip">Baidu Cloud Drive VIP?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="baidu-cloud-drive-vip"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For Baidu, I got &lt;code>3TB&lt;/code> from a promotion I participated in years ago, which is still sufficient. If you need more, you&amp;rsquo;ll have to buy VIP. To save money, you can look for discounts on Xianyu.&lt;/p>
&lt;h2 id="link-sharing-tips">
&lt;a class="heading-anchor-link" href="#link-sharing-tips">Link Sharing Tips&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="link-sharing-tips"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here are my personal suggestions, using Quark Cloud Drive as an example (other cloud drives are similar):&lt;/p>
&lt;ol>
&lt;li>Set links to &lt;strong>permanent validity&lt;/strong>—this way you can continue earning promotion revenue. Of course, if the cloud storage data itself needs an expiration date, that&amp;rsquo;s a different matter.&lt;/li>
&lt;li>Enable &lt;strong>auto-fill extraction code&lt;/strong> when sharing links, so it&amp;rsquo;s convenient for others to access.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/03/2026-03-18-221740.jpeg"
alt="https://static.1991421.cn/2026/03/2026-03-18-221740.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="combining-with-xianyu">
&lt;a class="heading-anchor-link" href="#combining-with-xianyu">Combining with Xianyu?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="combining-with-xianyu"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Combining with Xianyu is actually a great strategy. For example, you&amp;rsquo;ll see many pirated movies and software on Xianyu. As a seller, you earn money in two ways: 1) the product listing fee, and 2) when buyers download and transfer files, that generates cloud storage revenue. Even better, they might register cloud drive accounts or activate VIP—all generating additional revenue. So if you&amp;rsquo;re a seller or already a heavy cloud storage user, combining with Xianyu is definitely worthwhile.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Through this article, I hope you now understand where the profit comes from when people share content at scale. You often see 1-cent deals for resources on Xianyu—the monetization is essentially this cloud storage promotion model.&lt;/li>
&lt;li>This is advantageous because it has zero cost and actually generates income. The downside is that individual earnings may be modest. That said, if you play it right or are already a heavy cloud storage user, your earnings could be significantly higher.&lt;/li>
&lt;li>Don&amp;rsquo;t overthink it. If this sounds interesting to you, just get started.&lt;/li>
&lt;/ol></description></item><item><title>Xianyu Side Hustle Guide: From Zero to 1k+ Monthly Revenue</title><link>https://en.1991421.cn/2026/03/13/xianyu-side-hustle-guide-from-zero-to-1k-monthly-step-by-step/</link><pubDate>Fri, 13 Mar 2026 22:15:30 +0800</pubDate><guid>https://en.1991421.cn/2026/03/13/xianyu-side-hustle-guide-from-zero-to-1k-monthly-step-by-step/</guid><description>&lt;blockquote>
&lt;p>I usually play around with Xianyu, also nicknamed &amp;ldquo;Xiao Huang Yu&amp;rdquo;, in my spare time. At first, I only used it to sell used items and recover some cash. Later, I found that I could also sell software, materials, coupons, and similar products. Since I have a technical background, I started looking at each step from an engineering perspective: reducing costs, improving efficiency, and increasing sales. Looking back, it can now bring in around 1k per month. Once the income becomes meaningful, the whole thing starts to form a positive feedback loop.&lt;/p>
&lt;p>Here I am sharing many practical experiences that are hard to find online, for friends who want to try Xianyu as a side hustle.&lt;/p>
&lt;/blockquote>
&lt;p>Note: this article is &lt;code>continuously updated&lt;/code>. Xianyu is also commonly called Xiao Huang Yu in China.&lt;/p>
&lt;h2 id="the-value-of-xianyu">
&lt;a class="heading-anchor-link" href="#the-value-of-xianyu">The Value of Xianyu&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-value-of-xianyu"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Many people around me underestimate Xianyu. From a buyer&amp;rsquo;s perspective, they think it is low-end. From a seller&amp;rsquo;s perspective, they also think it is low-end. But that is naive. Look at the numbers.&lt;/p>
&lt;blockquote>
&lt;p>According to QuestMobile, Xianyu&amp;rsquo;s monthly active users (MAU) exceeded 200 million in March 2025, reaching 209 million, with year-over-year growth close to 20%. It entered the top ten &amp;ldquo;APP user scale growth list (100M+ MAU)&amp;rdquo; and ranked first in MAU growth among e-commerce apps.&lt;/p>
&lt;/blockquote>
&lt;h2 id="xianyu-the-dark-web-of-everyday-purchases">
&lt;a class="heading-anchor-link" href="#xianyu-the-dark-web-of-everyday-purchases">Xianyu: The &amp;ldquo;Dark Web&amp;rdquo; of Everyday Purchases&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xianyu-the-dark-web-of-everyday-purchases"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you do not know where to buy something in China, try searching on Xianyu. For example: Turkey Apple Card gift cards, ScreenStudio discount codes, Claude/GPT membership accounts, discount coupons, food delivery coupons, and so on. In short, many things can be found on Xianyu, including some things that are no longer easy to find on Taobao.&lt;/p>
&lt;p>Use Xianyu well, and you can make money. Use Xianyu well, and you can also save money. For example, when I go to arcades, I sometimes buy game tokens on Xianyu, which is cheaper than Meituan and similar platforms.&lt;/p>
&lt;h3 id="my-purchase-records">
&lt;a class="heading-anchor-link" href="#my-purchase-records">My Purchase Records&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-purchase-records"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>As the screenshots show, many unexpected things can be bought here. Even if you are not buying or selling used goods, some things are still suitable to buy on Xianyu. This is only for reference, but it may help open your thinking.&lt;/p>
&lt;p>I remember spending several thousand RMB on Xianyu last year, mainly on gift cards and game tokens.&lt;/p>
&lt;img src="https://static.1991421.cn/2026/03/2026-03-22-093416.png" alt="https://static.1991421.cn/2026/03/2026-03-22-093416.png" style="zoom:50%;" />
&lt;h2 id="my-xianyu-store-sales-revenue-data">
&lt;a class="heading-anchor-link" href="#my-xianyu-store-sales-revenue-data">My Xianyu Store Sales Revenue Data&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-xianyu-store-sales-revenue-data"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Back to the main topic: how much money can you make selling things on Xianyu? Here are some recent revenue numbers from my account.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/03/2026-03-22-093630.jpeg"
alt="https://static.1991421.cn/2026/03/2026-03-22-093630.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/03/2026-03-13-222317.jpeg"
alt="https://static.1991421.cn/2026/03/2026-03-13-222317.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>You can see the recent months are not bad. These numbers are only from the auto-delivery platform. Since some orders are not auto-delivered, the actual revenue is slightly higher.&lt;/p>
&lt;p>Now look at last year&amp;rsquo;s data. Since most revenue goes through Alipay, Alipay&amp;rsquo;s incoming payments can roughly reflect the income situation.&lt;/p>
&lt;img src="https://static.1991421.cn/2026/03/2026-03-13-222452.png" alt="https://static.1991421.cn/2026/03/2026-03-13-222452.png" style="zoom:50%;" />
&lt;p>Notes:&lt;/p>
&lt;ol>
&lt;li>You may wonder: by this calculation, 2025 did not reach 1k per month. That is true. I am not a professional seller, so it may not always reach that level. More objectively, I only really started playing seriously with Xianyu in the second half of the year. The first half was more about exploration.&lt;/li>
&lt;li>The store above is &lt;code>not a Yuxiaopu store&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>OK, now that you understand the revenue situation, let&amp;rsquo;s look at specific playbook suggestions. Of course, this is only one person&amp;rsquo;s experience. The income shown here only proves that the path is possible. If you do it better, the income may be higher. If you do it poorly, the income may be lower, or you may even lose money by spending a lot of ineffective time and effort. But if you never try, you lose one possible path, right?&lt;/p>
&lt;h2 id="xianyu-notes">
&lt;a class="heading-anchor-link" href="#xianyu-notes">Xianyu Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xianyu-notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="xianyu-accounts">
&lt;a class="heading-anchor-link" href="#xianyu-accounts">Xianyu Accounts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xianyu-accounts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Registering a Xianyu account is simple. The key thing to note is that Xianyu is bound to Alipay. In theory, each Xianyu account corresponds to one Alipay account, and one Chinese ID can have multiple Alipay accounts. So in theory, &lt;code>one ID can register multiple Xianyu accounts&lt;/code>. However, there are rumors that if one person has multiple Xianyu accounts, traffic may be limited. The official side has not confirmed this, and there is no solid business evidence, so I am only flagging it as a reminder.&lt;/p>
&lt;h3 id="should-you-open-yuxiaopu">
&lt;a class="heading-anchor-link" href="#should-you-open-yuxiaopu">Should You Open Yuxiaopu?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="should-you-open-yuxiaopu"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>After registering Xianyu as a seller, Xianyu will recommend opening Yuxiaopu. After opening it, you can get privileges such as group-buy discounts and a much higher product limit, from 50 items to 10,000. There are many benefits. So should you open it?&lt;/p>
&lt;ol>
&lt;li>I did not open it myself. The main reason is that I do not have more than 50 products, or rather, 50 is enough for now.&lt;/li>
&lt;li>Yuxiaopu has requirements such as shipping within 24 hours. Also, if there is a transaction dispute with a buyer, the rules are stricter for sellers.&lt;/li>
&lt;li>Think from the buyer&amp;rsquo;s perspective. If I buy professional items such as gift cards, buying from Yuxiaopu is fine. But if I buy genuinely used items such as phones, I tend to avoid Yuxiaopu, because Xianyu originally feels like a second-hand marketplace, not a professional seller platform. Yuxiaopu naturally labels you as a professional seller, which may scare away some buyers.&lt;/li>
&lt;/ol>
&lt;p>For these reasons, I did not open it. My personal advice for new sellers is to proceed step by step. You can skip it at first and open it later when scale or demand makes it necessary.&lt;/p>
&lt;h3 id="exposure-how-to-improve-it">
&lt;a class="heading-anchor-link" href="#exposure-how-to-improve-it">Exposure: How to Improve It&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="exposure-how-to-improve-it"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Pay attention to keywords in the title and description. If you do not know how to write them, search for similar products and see how others write their titles and descriptions, then imitate them. Copying is possible, but if you want users to choose you instead of others, you still need some differentiation. If everything is too homogeneous, users may not choose you.&lt;/li>
&lt;li>&lt;code>Xianyu coin deduction&lt;/code>: I always enable this myself. The downside is that your profit decreases. From Xianyu&amp;rsquo;s perspective, it cares more about transaction volume, because it is a platform and its model relies heavily on transactions. So it encourages users to use Xianyu coin deductions to improve exposure. But for sellers, this may reduce profit or even cause losses, so you need to weigh it yourself. If you can maintain profit, enabling it is better because it increases exposure and may lead to volume.&lt;/li>
&lt;li>&lt;code>Daily exposure&lt;/code>: you can tap it every day, collect Xianyu coins, and once you reach 100 coins, choose products to expose.&lt;/li>
&lt;li>&lt;code>Fast Sell&lt;/code>: go to My -&amp;gt; Xianyu Coins -&amp;gt; Fast Sell, then click to add exposure to a specific product. Note that the displayed number of exposed users is only a reference. In general, the more expensive the exposure, the more people it reaches.&lt;/li>
&lt;li>Red flowers: after each transaction ends, there is a &lt;code>request red flower&lt;/code> action. Tap it to send a message asking the buyer/seller for one. The official description does not say red flowers improve exposure, but from actual experience, at least it definitely does not hurt. So if possible, try it.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/03/2026-03-22-094626.jpeg"
alt="https://static.1991421.cn/2026/03/2026-03-22-094626.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="how-to-check-annual-income">
&lt;a class="heading-anchor-link" href="#how-to-check-annual-income">How to Check Annual Income&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-to-check-annual-income"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Xianyu itself does &lt;code>not show it directly&lt;/code>. Only at the end of the year does Xianyu send an annual report where you can see it.&lt;/li>
&lt;li>Another method is what I mentioned above: use Alipay bills and annual incoming payments. Strictly speaking, this is not fully accurate, because WeChat can also receive payments. The path is Alipay -&amp;gt; Me -&amp;gt; Bills -&amp;gt; Income and Expense Analysis -&amp;gt; Income -&amp;gt; Annual.&lt;/li>
&lt;/ol>
&lt;h3 id="how-to-handle-malicious-bad-reviews">
&lt;a class="heading-anchor-link" href="#how-to-handle-malicious-bad-reviews">How to Handle Malicious Bad Reviews&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-to-handle-malicious-bad-reviews"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>First, once a transaction is completed, even if you win through legal channels, the user can still leave a review and even insult you. There is no direct way to remove this type of bad review. However, if the user uses abusive language or defames you, you can report it. If the report succeeds, the review can be deleted. This is currently the &lt;code>only&lt;/code> practical solution.&lt;/li>
&lt;/ol>
&lt;h2 id="violations-restrictions-and-maintaining-xianqi-score">
&lt;a class="heading-anchor-link" href="#violations-restrictions-and-maintaining-xianqi-score">Violations, Restrictions, and Maintaining Xianqi Score&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="violations-restrictions-and-maintaining-xianqi-score"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The entry is My -&amp;gt; Safety Center -&amp;gt; Xianqi Score. Normally, we do not deliberately maintain this score, but once it drops below 80, Xianyu will forcibly delist all products. For example, I encounter violation deductions several times a year, causing the score to reach 80 or below, and then all products are delisted for one week. They recover after a week. When violation deductions lead to the account being locked for a week or even longer and unable to publish products, there are a few things we can do.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/04/2026-04-14-114918.png"
alt="https://static.1991421.cn/2026/04/2026-04-14-114918.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="before-problems-happen">
&lt;a class="heading-anchor-link" href="#before-problems-happen">Before Problems Happen&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="before-problems-happen"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>If a product has risk, do not publish it. The cost of point deductions is currently high. 80 is the key threshold. Also note that even if a product was not considered a violation before, relisting it may still be considered a violation, so pay attention to existing products too.&lt;/li>
&lt;li>If you want to play Xianyu long term, it is best to have multiple accounts. If one account gets points deducted, other accounts can still continue shipping. This acts like disaster recovery.&lt;/li>
&lt;li>In the Safety Center, some accounts may have tasks that earn points. If you see them, do them. I personally have not encountered them yet, so I can only wait for unblocking.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/04/2026-04-14-114605.png"
alt="https://static.1991421.cn/2026/04/2026-04-14-114605.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="after-problems-happen">
&lt;a class="heading-anchor-link" href="#after-problems-happen">After Problems Happen&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="after-problems-happen"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Appeal. In my own experience, I have never succeeded, but it is still worth trying.&lt;/li>
&lt;li>After unblocking, go through sold records, click details, and relist from there. This avoids editing the product again. Of course, do not relist products that were actually violations. If the product was penalized as a violation, relisting it will still be a violation and will deduct points again.&lt;/li>
&lt;/ol>
&lt;h3 id="what-happens-to-exposure-after-unblocking">
&lt;a class="heading-anchor-link" href="#what-happens-to-exposure-after-unblocking">What Happens to Exposure After Unblocking?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-happens-to-exposure-after-unblocking"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I have been restricted several times. Based on actual experience, &lt;code>exposure in the first week after unblocking&lt;/code> is not good, maybe only a few hundred views per day. But exposure is recovering during that period. The only thing you can do is add exposure yourself.&lt;/p>
&lt;h2 id="third-party-helper-agiso-auto-delivery">
&lt;a class="heading-anchor-link" href="#third-party-helper-agiso-auto-delivery">Third-Party Helper: Agiso Auto Delivery&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="third-party-helper-agiso-auto-delivery"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For product auto-delivery, I personally recommend buying Agiso&amp;rsquo;s auto-delivery service. It is currently &lt;code>138 RMB per year&lt;/code>. I recommend trying the free one-week trial first, then buying it if it fits.&lt;/p>
&lt;h3 id="auto-delivery-is-powerful">
&lt;a class="heading-anchor-link" href="#auto-delivery-is-powerful">Auto Delivery Is Powerful&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="auto-delivery-is-powerful"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>For example, you can enter a batch of codes, and each delivery can take one code from the pool, then reduce inventory by one. You can also repeatedly send the same content without reducing inventory.&lt;/li>
&lt;li>Delivery templates can be configured.&lt;/li>
&lt;li>It can automatically approve returns.&lt;/li>
&lt;/ol>
&lt;p>In short, these functions are all essential and greatly improve delivery and transaction efficiency.&lt;/p>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>It cannot automatically leave reviews. More precisely, this auto-delivery product cannot auto-review. For example, when a user confirms receipt, it cannot automatically initiate a review. Their Yudianzhang product can do this, but only if &lt;code>you open Yuxiaopu&lt;/code>. I personally do not want to open it, so there is no solution for me.&lt;/li>
&lt;/ol>
&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>It saves time and effort. Auto-delivery mainly solves delivery for no-inventory or digital products. With it, you can basically think of the process as requiring little manual work. Manual work is mostly for answering user questions.&lt;/li>
&lt;/ol>
&lt;h3 id="some-experience">
&lt;a class="heading-anchor-link" href="#some-experience">Some Experience&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="some-experience"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>During auto-delivery, you can choose to first send a delivery statement, giving the user a second confirmation opportunity. This avoids cases where some users buy, receive delivery, and immediately request a refund. In short, it gives users a chance to think again. The downside is lower delivery efficiency, but since it is automated, I think this extra step is acceptable for some products, such as high-priced items or products likely to generate returns. This is what I do personally.&lt;/li>
&lt;/ol>
&lt;h2 id="related-pages">
&lt;a class="heading-anchor-link" href="#related-pages">Related Pages&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-pages"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.agiso.com/" target="_blank" rel="noopener">Agiso&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>This article is still being updated. I will continue sharing more personal experience and tips later, so feel free to follow along.&lt;/li>
&lt;li>The content here is for reference only. Everyone&amp;rsquo;s situation is different, and what works for me may not work for you. Adjust and experiment based on your own reality.&lt;/li>
&lt;li>If you have any experience or questions about doing a Xianyu side hustle, feel free to share and discuss in the comments. We can learn from each other.&lt;/li>
&lt;/ol></description></item><item><title>OpenClaw (Lobster) Implementing Social Media Image-Text Publishing</title><link>https://en.1991421.cn/2026/03/11/openclaw-implement-social-media-publishing/</link><pubDate>Wed, 11 Mar 2026 23:25:13 +0800</pubDate><guid>https://en.1991421.cn/2026/03/11/openclaw-implement-social-media-publishing/</guid><description>&lt;blockquote>
&lt;p>Lobster is quite popular, but it doesn&amp;rsquo;t produce any new technology itself. It simply provides mainstream IM tools with the capability to leverage AI. So I thought it could also solve the daily publishing workflow for social media creators.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/03/2026-03-12-002100.jpeg"
alt="https://static.1991421.cn/2026/03/2026-03-12-002100.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="existing-skills">
&lt;a class="heading-anchor-link" href="#existing-skills">Existing Skills&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="existing-skills"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>First, let me introduce some existing skills. You can directly ask your AI to install these, and you can ask the AI for usage instructions.&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/JimLiu/baoyu-skills/tree/main/skills" target="_blank" rel="noopener">https://github.com/JimLiu/baoyu-skills/tree/main/skills&lt;/a>
Explanation: From Baoyu&amp;rsquo;s skills, I currently only use baoyu-cover-image (for generating article cover image prompts) and baoyu-post-to-wechat (for solving WeChat Official Account publishing issues).&lt;/li>
&lt;/ul>
&lt;p>For other platforms like Toutiao and Xiaohongshu, I&amp;rsquo;m currently developing them myself because they&amp;rsquo;re highly customized, so I won&amp;rsquo;t share them for now.&lt;/p>
&lt;h2 id="principles-of-social-media-publishing">
&lt;a class="heading-anchor-link" href="#principles-of-social-media-publishing">Principles of Social Media Publishing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="principles-of-social-media-publishing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>For platforms like Xiaohongshu and Toutiao, since they have PC web interfaces, you can use Playwright to simulate browser operations. Of course, you could also use API interfaces, but they&amp;rsquo;re too easily blocked. I personally recommend directly manipulating the web pages.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>For WeChat Official Account, since there&amp;rsquo;s an &lt;a href="https://developers.weixin.qq.com/platform" target="_blank" rel="noopener">official API&lt;/a>, the aforementioned Skill recommends using the official API method for publishing, as it&amp;rsquo;s more stable. Of course, Baoyu&amp;rsquo;s skill is compatible with both API and non-API approaches. Without an API, it naturally falls back to browser page operations.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="image-generation">
&lt;a class="heading-anchor-link" href="#image-generation">Image Generation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="image-generation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Compared to GPT and Gemini, Gemini is much more powerful. Chinese character rendering is now good without obvious issues. Since API pricing is a threshold issue and costs are a concern, I&amp;rsquo;m using the web-based solution directly. That is, using Playwright to simulate browser operations, generating images directly on the web page, and downloading them locally. This way, you can continue with image-text publishing.&lt;/p>
&lt;h2 id="writing-skills">
&lt;a class="heading-anchor-link" href="#writing-skills">Writing Skills&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="writing-skills"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Although there are some solutions online, whether for security or customization reasons, you always end up needing to modify them. So how to write efficiently? Here&amp;rsquo;s my approach: I use the Chrome Claude plugin to write directly on the target page. This way, Claude helps generate the rough code and also verifies its effectiveness. Then I can copy the basic logic and have OpenClaw re-encapsulate it.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>So far, the most critical image generation and publishing are sorted out. This actually saves considerable time, and it also makes it easy to do multi-platform simultaneous publishing. So, let&amp;rsquo;s get to it!&lt;/p></description></item><item><title>Getting the iPhone 17 via JD Trade-In: Great Bare-Hand Feel</title><link>https://en.1991421.cn/2026/02/15/iphone-17-jd-trade-in-experience/</link><pubDate>Sun, 15 Feb 2026 11:46:41 +0800</pubDate><guid>https://en.1991421.cn/2026/02/15/iphone-17-jd-trade-in-experience/</guid><description>&lt;blockquote>
&lt;p>I bought the 16 Pro in May 2025 for &lt;code>5469 CNY&lt;/code>. Recently it started lagging, and I found out the 128GB storage was almost full (only a few GB left). I had to delete some apps and move photos to Quark cloud storage. The lag improved, but the core storage issue remained.&lt;/p>
&lt;p>I happened to see on Xiaohongshu that JD was running another Apple trade-in promotion, so I decided to upgrade. While the phone is still relatively new and worth more, I traded up to the 17.&lt;/p>
&lt;p>Here I&amp;rsquo;ll document my process and experience.&lt;/p>
&lt;/blockquote>
&lt;h2 id="purchase-motivation">
&lt;a class="heading-anchor-link" href="#purchase-motivation">Purchase Motivation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchase-motivation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>My 16 Pro only had &lt;code>128G&lt;/code> storage, which was too small.&lt;/li>
&lt;/ol>
&lt;p>That&amp;rsquo;s the only reason for upgrading. Nothing else to complain about - I&amp;rsquo;m a long-time Apple user, and iPhone has always been stable and well-balanced. No reason to switch brands.&lt;/p>
&lt;h2 id="trade-in-plan">
&lt;a class="heading-anchor-link" href="#trade-in-plan">Trade-In Plan&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="trade-in-plan"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Having decided to go from 16 to 17, there were multiple 17 models to choose from (17, 17 Air, 17 Pro, 17 Pro Max) - Tim Cook&amp;rsquo;s product segmentation is still masterful. But considering the upgrade cost and not wanting to pay too much extra, the decision was simple. After 10 minutes of thought, I chose the base 17 model with &lt;code>256G&lt;/code> storage, which is enough for me.&lt;/p>
&lt;p>The upgrade cost breakdown looks reasonable - I only paid &lt;code>450 CNY&lt;/code> extra. JD essentially provided both &lt;code>government subsidy + trade-in bonus&lt;/code>, which I think is pretty good.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/02/2026-02-15-120114.jpeg"
alt="https://static.1991421.cn/2026/02/2026-02-15-120114.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/02/2026-02-15-120320.jpeg"
alt="https://static.1991421.cn/2026/02/2026-02-15-120320.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Tip: The government subsidy has a yearly quota. For example, my 16 Pro used the 2025 phone subsidy, and this trade-in uses the 2026 quota - they don&amp;rsquo;t conflict.&lt;/strong>&lt;/p>
&lt;h2 id="trade-in-method">
&lt;a class="heading-anchor-link" href="#trade-in-method">Trade-In Method&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="trade-in-method"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I personally chose the &lt;code>one-time home visit&lt;/code> option, mainly for convenience. AiHuiShou (the recycling service) calls to schedule a home visit. If the old phone passes inspection, you sign and hand it over, then receive the new phone. If there are issues during inspection, they might try to lower the price. In my case there was no price reduction. Personally, I think if they try to negotiate, you can simply refuse the deal. Considering the cost of a home visit, maybe AiHuiShou would just let it go.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/02/2026-02-15-121055.jpeg"
alt="https://static.1991421.cn/2026/02/2026-02-15-121055.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="data-clearing">
&lt;a class="heading-anchor-link" href="#data-clearing">Data Clearing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="data-clearing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>AiHuiShou will wipe your phone data on the spot. It&amp;rsquo;s recommended to back up beforehand — you can use a MacBook for backup and then sync directly to the new phone. Alternatively, you can pay a deposit and mail the phone to AiHuiShou later. I had mine wiped on the spot to ensure privacy.&lt;/p>
&lt;h2 id="accessories">
&lt;a class="heading-anchor-link" href="#accessories">Accessories&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After getting the phone, I needed accessories. I still only got &lt;code>2 items&lt;/code>:&lt;/p>
&lt;ol>
&lt;li>SHANMO tempered glass screen protector, from JD, &lt;code>23 CNY&lt;/code>&lt;/li>
&lt;li>Huaqiangbei iPhone MagSafe case, from PDD, &lt;code>45 CNY&lt;/code>&lt;/li>
&lt;/ol>
&lt;img src="https://static.1991421.cn/2026/02/2026-02-15-124216.JPG" alt="https://static.1991421.cn/2026/02/2026-02-15-124216.JPG" style="zoom:50%;" />
&lt;p>After trying them out, I found that the old 16 Pro screen protector and case actually fit perfectly - they&amp;rsquo;re compatible. If you don&amp;rsquo;t want to spend money, just use your old accessories.&lt;/p>
&lt;h2 id="current-experience">
&lt;a class="heading-anchor-link" href="#current-experience">Current Experience&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-experience"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The build quality is excellent. While the base 17 doesn&amp;rsquo;t look dramatically different, the material quality feels better, and the back has a very comfortable hand feel.&lt;/li>
&lt;li>The front camera has a noticeably visible improvement, going from &lt;code>12 megapixels&lt;/code> to &lt;code>18 megapixels&lt;/code>.&lt;/li>
&lt;/ol>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The annoying button layout still hasn&amp;rsquo;t been fixed. Let me copy my complaint from last time:&lt;/p>
&lt;ol>
&lt;li>Both the left-side mute button and volume buttons are buttons, causing me to frequently &lt;code>accidentally press&lt;/code> them when pressing blindly. I think this design is a failure and suspect the iPhone team&amp;rsquo;s testing wasn&amp;rsquo;t thorough enough.&lt;/li>
&lt;li>The camera button on the right side, I admit, is convenient when taking photos, but without it there wouldn&amp;rsquo;t be much of a problem, so isn&amp;rsquo;t it quite &lt;code>redundant&lt;/code>? Simplicity no longer exists, making the physical buttons feel very bloated. The overall design aesthetics of the iPhone is at least far worse than the iPhone 4 era. The Cook era always feels like the aesthetics have deteriorated significantly, let alone surpassing previous designs.&lt;/li>
&lt;/ol>
&lt;h3 id="upgrading-doesnt-always-mean-better">
&lt;a class="heading-anchor-link" href="#upgrading-doesnt-always-mean-better">Upgrading Doesn&amp;rsquo;t Always Mean Better?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="upgrading-doesnt-always-mean-better"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>There are actually quite a few differences between the Pro and base models that you might not notice. You get what you pay for. Of course, if your usage is fairly basic, the base model is fine - you save money after all. But it&amp;rsquo;s good to know these differences so you don&amp;rsquo;t assume everything is an upgrade.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/02/2026-02-15-124729.png"
alt="https://static.1991421.cn/2026/02/2026-02-15-124729.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="what-about-my-old-iphone-12-and-14-base-models">
&lt;a class="heading-anchor-link" href="#what-about-my-old-iphone-12-and-14-base-models">What About My Old iPhone 12 and 14 Base Models?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-about-my-old-iphone-12-and-14-base-models"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After trading the 16 for the 17, I still have 2 other phones. I calculated the trade-in costs - one would need 3000+ CNY extra, the other 4000+ CNY. On second thought, I&amp;rsquo;ll pass for now. If I really wanted to trade them in, getting an iPad mini cellular version could be an option.&lt;/p>
&lt;img src="https://static.1991421.cn/2026/02/2026-02-15-122000.jpg" alt="https://static.1991421.cn/2026/02/2026-02-15-122000.jpg" style="zoom:60%;" />
&lt;h2 id="my-apple-ecosystem">
&lt;a class="heading-anchor-link" href="#my-apple-ecosystem">My Apple Ecosystem&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-apple-ecosystem"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>From 2025 to now, I&amp;rsquo;ve upgraded several Apple devices. Periodically refreshing the lineup is nice - one of Apple&amp;rsquo;s biggest draws is the ecosystem.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/02/2026-02-15-124920.png"
alt="https://static.1991421.cn/2026/02/2026-02-15-124920.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>JD&amp;rsquo;s trade-in program is decent. If you&amp;rsquo;re looking to upgrade, it&amp;rsquo;s a good deal worth taking advantage of. Compared to selling through recycling services or on Xianyu (second-hand market), it saves you the time and hassle.&lt;/li>
&lt;li>Complaints aside, Apple products consistently have high sales for good reason. I&amp;rsquo;ve always thought they&amp;rsquo;re solid. Of course, the perpetually delayed AI (partly not Apple&amp;rsquo;s fault) deserves criticism - it borders on false advertising.&lt;/li>
&lt;li>The base iPhone 17 is already quite generous - 256GB storage starting point, high refresh rate, front camera upgrade, etc. Even without trade-in discounts, it&amp;rsquo;s a solid device. Though if you&amp;rsquo;re used to Android&amp;rsquo;s big batteries, there&amp;rsquo;s still room for complaints.&lt;/li>
&lt;/ol>
&lt;p>In short, I hope Apple AI comes to the China market soon.&lt;/p></description></item><item><title>Implement Custom Domain Email with QQ Mail</title><link>https://en.1991421.cn/2026/02/08/implement-custom-domain-email-with-qq-mail/</link><pubDate>Sun, 08 Feb 2026 15:23:01 +0800</pubDate><guid>https://en.1991421.cn/2026/02/08/implement-custom-domain-email-with-qq-mail/</guid><description>&lt;blockquote>
&lt;p>I use Gmail more often, but it doesn&amp;rsquo;t support custom domain emails. QQ Mail does support custom domain emails, so this article introduces how to implement a custom domain email with QQ Mail.&lt;/p>
&lt;/blockquote>
&lt;h2 id="why-not-use-cloudflare">
&lt;a class="heading-anchor-link" href="#why-not-use-cloudflare">Why Not Use Cloudflare&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-not-use-cloudflare"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I considered using Cloudflare, which can solve email sending/receiving with custom domains. However, the free version of Cloudflare doesn&amp;rsquo;t support SMTP protocol - it only supports POP3/IMAP for email retrieval, not SMTP for sending emails.&lt;/p>
&lt;p>So I gave up on that. Self-hosting also requires costs, so I still chose to use QQ Mail&amp;rsquo;s custom domain email feature.&lt;/p>
&lt;h2 id="qq-mail-custom-domain-now-requires-payment">
&lt;a class="heading-anchor-link" href="#qq-mail-custom-domain-now-requires-payment">QQ Mail Custom Domain Now Requires Payment&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="qq-mail-custom-domain-now-requires-payment"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>QQ Mail&amp;rsquo;s custom domain email feature is &lt;code>no longer free&lt;/code>. You need to purchase an enterprise email package to use the custom domain email feature. For specific prices, please refer to Tencent Enterprise Email official website. It&amp;rsquo;s approximately 300 CNY per year. I personally bound my custom domain many years ago, so it&amp;rsquo;s still available, but I can&amp;rsquo;t bind new custom domains. If I cancel it, I can&amp;rsquo;t bind it again.&lt;/p>
&lt;h2 id="steps-to-bind-custom-domain-email">
&lt;a class="heading-anchor-link" href="#steps-to-bind-custom-domain-email">Steps to Bind Custom Domain Email&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="steps-to-bind-custom-domain-email"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Add an MX record &lt;code>mxdomain.qq.com&lt;/code> in your DNS records, pointing to QQ Mail&amp;rsquo;s server address.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2026/02/2026-02-08-153434.jpeg"
alt="https://static.1991421.cn/2026/02/2026-02-08-153434.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/li>
&lt;li>If you haven&amp;rsquo;t logged in to QQ Mail on your local client yet, you need to log in first. Note that the password is not your QQ account password but an authorization password. The login account should be your QQ number, not the custom domain email account.&lt;/li>
&lt;li>Add your custom domain in QQ Mail, then add domain email accounts. Each account requires binding to a QQ number.&lt;/li>
&lt;li>After logging in, you can add the custom domain account as a sender in email clients like Mac Mail.&lt;/li>
&lt;li>Sending emails directly with the custom domain email may fail. Normally, you will receive an email notifying you that the MX record has been added successfully.&lt;/li>
&lt;/ol>
&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>If QQ Mail detects that the MX record is invalid, it will send an email. If not fixed within 30 days, the custom domain email will become unavailable. This is especially important for free users like me. If it becomes invalid and you try to fix it, you might have to pay. So I recommend that if you use a custom domain email as a free user, pay attention to such emails and fix the MX record promptly.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For me, being able to use a custom domain email without additional costs is a great choice. Especially since it&amp;rsquo;s now a paid feature, it feels like I&amp;rsquo;m saving 300 CNY every year.&lt;/p></description></item><item><title>My Subscribed Software Services List</title><link>https://en.1991421.cn/2025/11/16/my-subscribed-services-list/</link><pubDate>Sun, 16 Nov 2025 22:28:25 +0800</pubDate><guid>https://en.1991421.cn/2025/11/16/my-subscribed-services-list/</guid><description>&lt;blockquote>
&lt;p>As a heavy internet user, I subscribe to a variety of services. Here, I’d like to share the primary services I currently use and how they help me.&lt;/p>
&lt;/blockquote>
&lt;img src="https://static.1991421.cn/2025/2025-12-28-222536.png" alt="my-subscribed-services-list-1" style="zoom:50%;" />
&lt;h2 id="list-of-subscription-services">
&lt;a class="heading-anchor-link" href="#list-of-subscription-services">List of Subscription Services&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="list-of-subscription-services"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="streaming-services">
&lt;a class="heading-anchor-link" href="#streaming-services">Streaming Services&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="streaming-services"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;h4 id="youtube-premium">YouTube Premium&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: Ad-free viewing, background play, and a vast library of content.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: Turkey&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Monthly (104.9 TRY/month)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: ~240 CNY&lt;/li>
&lt;/ul>
&lt;h4 id="spotify-premium">Spotify Premium&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: Music streaming service, ad-free, and focused on the listening experience.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: Turkey&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Family Plan (Shared)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: ~95 CNY&lt;/li>
&lt;/ul>
&lt;h3 id="ai-tools">
&lt;a class="heading-anchor-link" href="#ai-tools">AI Tools&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ai-tools"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;h4 id="chatgpt-plus">ChatGPT Plus&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: Access to GPT-4o/o1 models, with strong voice and web browsing capabilities.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: Turkey&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Monthly (499 TRY/month)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: ~1,080 CNY&lt;/li>
&lt;/ul>
&lt;h4 id="claude-pro">Claude Pro&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: Assistance with writing and access to Claude Code.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: Nigeria&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Monthly (14,900 NGN/month)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: ~1,056 CNY&lt;/li>
&lt;/ul>
&lt;h3 id="social-platforms">
&lt;a class="heading-anchor-link" href="#social-platforms">Social Platforms&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="social-platforms"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;h4 id="x-premium">X Premium&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: Member benefits such as editing posts; eligible accounts can also participate in the revenue-sharing program.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: Turkey&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Monthly (199.99 TRY/month)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: ~330 CNY&lt;/li>
&lt;/ul>
&lt;h3 id="productivity-tools">
&lt;a class="heading-anchor-link" href="#productivity-tools">Productivity Tools&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="productivity-tools"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;h4 id="1password">1Password&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: Password manager with multi-platform synchronization.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: N/A&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Open Source License (Free)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: 0 CNY&lt;/li>
&lt;/ul>
&lt;h4 id="github-copilot">GitHub Copilot&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: AI-powered code completion for VS Code.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: N/A&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Educational Eligibility (Free)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: 0 CNY&lt;/li>
&lt;/ul>
&lt;h3 id="cloud-storage-and-servers">
&lt;a class="heading-anchor-link" href="#cloud-storage-and-servers">Cloud Storage and Servers&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cloud-storage-and-servers"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;h4 id="icloud">iCloud&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: 200GB storage space for data backup.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: China&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Monthly (21 CNY/month)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: 252 CNY&lt;/li>
&lt;/ul>
&lt;h4 id="proxy-services-airport">Proxy Services (Airport)&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: Pro lines with 500GB/month data.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: N/A&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Annual (Promotional price)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: 470 CNY&lt;/li>
&lt;/ul>
&lt;h4 id="tencent-cloud-vps">Tencent Cloud VPS&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: Lightweight Application Server for hosting personal services and websites.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: China&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Annual (Promotional price)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: 99 CNY&lt;/li>
&lt;/ul>
&lt;h3 id="membership-benefits">
&lt;a class="heading-anchor-link" href="#membership-benefits">Membership Benefits&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="membership-benefits"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;h4 id="jd-plus">JD Plus&lt;/h4>&lt;ul>
&lt;li>&lt;strong>Description&lt;/strong>: Shopping rewards (Jingdou), shipping benefits, and free delivery.&lt;/li>
&lt;li>&lt;strong>Region&lt;/strong>: China&lt;/li>
&lt;li>&lt;strong>Subscription Type&lt;/strong>: Annual (Discounted via third-party channels)&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: ~70 CNY&lt;/li>
&lt;/ul>
&lt;h3 id="total-expenditure">
&lt;a class="heading-anchor-link" href="#total-expenditure">Total Expenditure&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="total-expenditure"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;strong>Total Annual Cost&lt;/strong>: &lt;strong>3,692 CNY&lt;/strong>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>These are the main services I currently subscribe to. At a rough calculation, the annual cost is &lt;strong>3,692 CNY&lt;/strong>. If I didn&amp;rsquo;t take advantage of lower-priced regions or special promotions, the cost would be significantly higher. However, for a heavy internet user like myself, these services greatly enhance my experience and efficiency, making them well worth the investment.&lt;/li>
&lt;li>In addition to these, there are smaller costs like domain registrations, but since they aren&amp;rsquo;t as significant, I won’t detail them here.&lt;/li>
&lt;/ol></description></item><item><title>Subscribing to YouTube Premium via Turkey (2025 Guide)</title><link>https://en.1991421.cn/2025/10/20/youtube-turkey-membership-2025/</link><pubDate>Mon, 20 Oct 2025 18:54:03 +0800</pubDate><guid>https://en.1991421.cn/2025/10/20/youtube-turkey-membership-2025/</guid><description>&lt;blockquote>
&lt;p>My previous shared YouTube family plan was canceled, likely due to Google’s stricter enforcement of regional IP consistency within families. To ensure stability, I decided to manage my own subscription. Since direct card payments in the Turkey region usually require a locally issued bank card, I opted for the Apple App Store subscription method instead. Here’s how I did it.&lt;/p>
&lt;/blockquote>
&lt;h2 id="prerequisites">
&lt;a class="heading-anchor-link" href="#prerequisites">Prerequisites&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="prerequisites"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Turkish Apple ID&lt;/strong>: You can easily create a new one or switch an existing account to the Turkey region. I already had one on hand, so I used that.&lt;/li>
&lt;li>&lt;strong>Google Account&lt;/strong>: Ensure the account you want to use is not currently part of any active subscription or family plan.&lt;/li>
&lt;/ol>
&lt;h2 id="funding-your-turkish-apple-id">
&lt;a class="heading-anchor-link" href="#funding-your-turkish-apple-id">Funding Your Turkish Apple ID&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="funding-your-turkish-apple-id"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I purchased a 500 TRY (Turkish Lira) Apple Gift Card from a third-party marketplace (like Xianyu or SeaGM). The cost was approximately &lt;strong>88 CNY&lt;/strong>. Once you receive the code, redeem it directly on your Turkish Apple ID.&lt;/p>
&lt;p>Alternatively, you can purchase a Turkish iTunes Gift Card directly below (500 TRY/card, USD $14). Note that a small exchange rate conversion cost is included, so it&amp;rsquo;s slightly above the local direct price.&lt;/p>
&lt;div class="tgcs-card">
&lt;div class="tgcs-header">
&lt;div class="tgcs-header-icon">🎁&lt;/div>
&lt;div>
&lt;div class="tgcs-title">Turkish iTunes Gift Card&lt;/div>
&lt;div class="tgcs-subtitle">500 TRY/card · Delivered within 24 hrs · Exchange rate conversion applies — slightly above direct local price&lt;/div>
&lt;/div>
&lt;div class="tgcs-price-tag">USD $14&lt;span>/card&lt;/span>&lt;/div>
&lt;/div>
&lt;div class="tgcs-notice">💡 $14/card · Fixed price · Exchange rate loss included&lt;/div>
&lt;div class="tgcs-body">
&lt;div class="tgcs-qty-row">
&lt;span class="tgcs-label">Quantity&lt;/span>
&lt;div class="tgcs-qty-ctrl">
&lt;button class="tgcs-qty-btn cursor-pointer" id="tgcs-minus">−&lt;/button>
&lt;span id="tgcs-qty-display">2&lt;/span>
&lt;button class="tgcs-qty-btn cursor-pointer" id="tgcs-plus">+&lt;/button>
&lt;/div>
&lt;span class="tgcs-total" id="tgcs-total">Total: USD $28&lt;/span>
&lt;/div>
&lt;div class="tgcs-email-row">
&lt;input
type="email"
id="tgcs-email"
class="tgcs-email-input"
placeholder="Your email (to receive the card code)"
/>
&lt;/div>
&lt;button id="tgcs-buy-btn" class="tgcs-buy-btn cursor-pointer">
Pay with Card
&lt;/button>
&lt;p id="tgcs-msg" class="tgcs-msg" style="display:none">&lt;/p>
&lt;p class="tgcs-note">
After payment, the gift card code will be sent to your email within 24 hours.
&lt;/p>
&lt;details class="payment-faq">
&lt;summary>Payment issues?&lt;/summary>
&lt;div class="payment-faq-body">If you see 'payment blocked' or 'too risky', this is Stripe's automated fraud prevention — not a merchant decision. Common causes and fixes:&lt;br>&lt;br>&lt;strong>1. VPN / Proxy&lt;/strong>&lt;br>Turn off your VPN or switch to a node matching your card's issuing country. IP-to-card country mismatch often triggers the block.&lt;br>&lt;br>&lt;strong>2. Card not enabled for international payments&lt;/strong>&lt;br>Make sure your credit/debit card has international online transactions enabled — some banks disable this by default.&lt;br>&lt;br>&lt;strong>3. Try a different card&lt;/strong>&lt;br>Prefer Visa / Mastercard credit cards. Prepaid or virtual cards are more likely to be blocked.&lt;br>&lt;br>&lt;strong>4. Browser issues&lt;/strong>&lt;br>Try incognito/private mode, or a different browser. Some extensions can interfere with the payment flow.&lt;br>&lt;br>&lt;strong>5. Still not working?&lt;/strong>&lt;br>Contact the author via Alipay or PayPal to complete the payment.&lt;/div>
&lt;/details>
&lt;/div>
&lt;/div>
&lt;script>
(function () {
var qty = 2;
var min = 1;
var max = 5;
var unitPrice = 14;
var btn = document.getElementById('tgcs-buy-btn');
var msg = document.getElementById('tgcs-msg');
function updateDisplay() {
document.getElementById('tgcs-qty-display').textContent = qty;
document.getElementById('tgcs-total').textContent = 'Total: USD $' + (qty * unitPrice);
document.getElementById('tgcs-minus').disabled = qty &lt;= min;
document.getElementById('tgcs-plus').disabled = qty >= max;
}
document.getElementById('tgcs-minus').addEventListener('click', function () {
if (qty > min) { qty--; updateDisplay(); }
});
document.getElementById('tgcs-plus').addEventListener('click', function () {
if (qty &lt; max) { qty++; updateDisplay(); }
});
btn.addEventListener('click', function () {
var email = document.getElementById('tgcs-email').value.trim();
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
msg.style.display = 'block';
msg.className = 'tgcs-msg tgcs-msg-error';
msg.textContent = 'Please enter a valid email address.';
return;
}
btn.disabled = true;
btn.textContent = 'Redirecting...';
msg.style.display = 'none';
fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'turkey_gift_card', quantity: qty, email: email, returnUrl: window.location.href }),
})
.then(function (r) { return r.json(); })
.then(function (data) {
if (data.url) {
window.location.href = data.url;
} else {
msg.style.display = 'block';
msg.className = 'tgcs-msg tgcs-msg-error';
msg.textContent = data.error || 'Something went wrong. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
}
})
.catch(function () {
msg.style.display = 'block';
msg.className = 'tgcs-msg tgcs-msg-error';
msg.textContent = 'Network error. Please try again.';
btn.disabled = false;
btn.textContent = 'Pay with Card';
});
});
})();
&lt;/script>
&lt;style>
.tgcs-card {
margin: 1.5rem 0;
border-radius: 14px;
border: 1px solid #dbeafe;
background: #fff;
overflow: hidden;
box-shadow: 0 2px 12px rgba(37, 99, 235, 0.08);
}
:root.dark .tgcs-card {
background: #1a2035;
border-color: #1e3a5f;
}
.tgcs-header {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem 1.25rem;
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
color: white;
}
.tgcs-header-icon {
font-size: 1.75rem;
flex-shrink: 0;
}
.tgcs-title {
font-size: 1rem;
font-weight: 700;
}
.tgcs-subtitle {
font-size: 0.8rem;
opacity: 0.85;
margin-top: 2px;
}
.tgcs-price-tag {
margin-left: auto;
font-size: 1.5rem;
font-weight: 800;
white-space: nowrap;
}
.tgcs-price-tag span {
font-size: 0.85rem;
font-weight: 400;
opacity: 0.85;
}
.tgcs-notice {
padding: 0.5rem 1.25rem;
font-size: 0.8rem;
color: #1e40af;
background: #eff6ff;
border-top: 1px solid #bfdbfe;
}
:root.dark .tgcs-notice {
color: #93c5fd;
background: #172554;
border-color: #1e3a8a;
}
.tgcs-body {
padding: 1.25rem;
display: flex;
flex-direction: column;
gap: 0.875rem;
}
.tgcs-qty-row {
display: flex;
align-items: center;
gap: 0.75rem;
}
.tgcs-label {
font-size: 0.9rem;
color: #374151;
font-weight: 500;
}
:root.dark .tgcs-label {
color: #d1d5db;
}
.tgcs-qty-ctrl {
display: flex;
align-items: center;
gap: 0;
border: 1px solid #d1d5db;
border-radius: 8px;
overflow: hidden;
}
:root.dark .tgcs-qty-ctrl {
border-color: #374151;
}
.tgcs-qty-btn {
width: 32px;
height: 32px;
border: none;
background: #f9fafb;
color: #374151;
font-size: 1.1rem;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.15s;
}
:root.dark .tgcs-qty-btn {
background: #374151;
color: #e5e7eb;
}
.tgcs-qty-btn:hover:not(:disabled) {
background: #e5e7eb;
}
:root.dark .tgcs-qty-btn:hover:not(:disabled) {
background: #4b5563;
}
.tgcs-qty-btn:disabled {
opacity: 0.35;
cursor: not-allowed;
}
#tgcs-qty-display {
min-width: 32px;
text-align: center;
font-size: 0.95rem;
font-weight: 600;
color: #111827;
}
:root.dark #tgcs-qty-display {
color: #f9fafb;
}
.tgcs-total {
margin-left: auto;
font-size: 0.95rem;
font-weight: 700;
color: #2563eb;
}
.tgcs-email-row {
display: flex;
}
.tgcs-email-input {
width: 100%;
padding: 0.6rem 0.875rem;
border: 1px solid #d1d5db;
border-radius: 8px;
font-size: 0.9rem;
color: #111827;
background: #fff;
box-sizing: border-box;
transition: border-color 0.2s;
outline: none;
}
:root.dark .tgcs-email-input {
background: #1f2937;
border-color: #374151;
color: #f3f4f6;
}
.tgcs-email-input:focus {
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.tgcs-buy-btn {
width: 100%;
padding: 0.7rem;
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
color: white;
border: none;
border-radius: 8px;
font-size: 0.95rem;
font-weight: 600;
transition: opacity 0.2s, transform 0.15s;
}
.tgcs-buy-btn:hover:not(:disabled) {
opacity: 0.92;
transform: translateY(-1px);
}
.tgcs-buy-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.tgcs-msg {
font-size: 0.85rem;
padding: 0.5rem 0.75rem;
border-radius: 6px;
margin: 0;
}
.tgcs-msg-error {
background: #fef2f2;
color: #dc2626;
}
:root.dark .tgcs-msg-error {
background: #3f1515;
color: #f87171;
}
.tgcs-note {
font-size: 0.8rem;
color: #9ca3af;
margin: 0;
text-align: center;
}
&lt;/style>
&lt;h2 id="the-subscription-process">
&lt;a class="heading-anchor-link" href="#the-subscription-process">The Subscription Process&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-subscription-process"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Set your proxy/VPN&lt;/strong>: Set your global proxy to a neutral region (or Turkey if possible).&lt;/li>
&lt;li>&lt;strong>Log in to YouTube&lt;/strong>: Open the YouTube app on your iPhone using the Google account you intend to upgrade.&lt;/li>
&lt;li>&lt;strong>Check Pricing&lt;/strong>: Navigate to &lt;strong>Account &amp;gt; Get YouTube Premium&lt;/strong>. Because you are logged into a Turkish Apple ID, YouTube should display the price in Lira (currently &lt;strong>104.99 TRY/month&lt;/strong>).&lt;/li>
&lt;li>&lt;strong>Subscribe&lt;/strong>: Confirm the subscription. Since your Apple ID already has a balance from the gift card, it will use that for payment—no need for a Turkish credit card or PayPal.&lt;/li>
&lt;li>&lt;strong>Confirmation&lt;/strong>: You&amp;rsquo;ll receive a notification once the subscription is active.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-10-20-204743.jpeg"
alt="YouTube Turkey Premium Subscription"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Since I used a fresh account, I received the first month for free, with billing starting in the second month.&lt;/p>
&lt;h2 id="annual-cost-breakdown">
&lt;a class="heading-anchor-link" href="#annual-cost-breakdown">Annual Cost Breakdown&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="annual-cost-breakdown"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For those who want a quick estimate:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Monthly Cost&lt;/strong>: 104.99 TRY&lt;/li>
&lt;li>&lt;strong>Annual Cost&lt;/strong>: 104.99 * 12 = 1,259.88 TRY&lt;/li>
&lt;li>&lt;strong>CNY Equivalent&lt;/strong>: At a gift card rate of 88 CNY per 500 TRY, the total annual cost is roughly &lt;strong>221.34 CNY&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;p>&lt;em>(Note: Prices may fluctuate slightly due to exchange rate changes and gift card pricing.)&lt;/em>&lt;/p>
&lt;h2 id="important-tips">
&lt;a class="heading-anchor-link" href="#important-tips">Important Tips&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="important-tips"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Avoid frequent IP switching&lt;/strong>: I generally use a consistent proxy region (like Japan) for daily viewing to avoid triggering security flags.&lt;/li>
&lt;li>&lt;strong>Auto-renewal&lt;/strong>: Ensure you keep enough balance in your Apple ID to cover the monthly renewal.&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>For me, YouTube Premium is a must-have—the ads have become unbearable. If you&amp;rsquo;re looking for a cheaper way to subscribe, the Turkey region via Apple ID is a solid, relatively low-maintenance option.&lt;/li>
&lt;li>Enjoy it while it lasts! These &amp;ldquo;regional loopholes&amp;rdquo; are often patched by Google eventually, so cherish the savings while you can.&lt;/li>
&lt;/ol></description></item><item><title>Extending Caddy Functionality by Installing Modules</title><link>https://en.1991421.cn/2025/09/24/caddy-install-modules/</link><pubDate>Wed, 24 Sep 2025 23:02:16 +0800</pubDate><guid>https://en.1991421.cn/2025/09/24/caddy-install-modules/</guid><description>&lt;blockquote>
&lt;p>I recently had a requirement where I needed Caddy to inject a custom JavaScript snippet into the HTML responses of a proxied web service. After some research, I found that this can be achieved by installing a specific Caddy module. Since I hadn&amp;rsquo;t worked with Caddy modules before, I spent some time learning how to install and configure them.&lt;/p>
&lt;/blockquote>
&lt;h2 id="caddys-modular-architecture">
&lt;a class="heading-anchor-link" href="#caddys-modular-architecture">Caddy&amp;rsquo;s Modular Architecture&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="caddys-modular-architecture"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Caddy is built as a collection of modules. While the default distribution includes the most common features, it doesn&amp;rsquo;t include everything—even official modules. To add a specific module, you must recompile Caddy with that module included.&lt;/p>
&lt;h2 id="checking-installed-modules">
&lt;a class="heading-anchor-link" href="#checking-installed-modules">Checking Installed Modules&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="checking-installed-modules"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>You can verify which modules are currently active in your Caddy binary using the following commands:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># List all installed modules&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">caddy list-modules
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Search for a specific module (e.g., &amp;#39;replace&amp;#39;)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">caddy list-modules &lt;span class="p">|&lt;/span> grep replace
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="customizing-caddy-via-docker">
&lt;a class="heading-anchor-link" href="#customizing-caddy-via-docker">Customizing Caddy via Docker&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="customizing-caddy-via-docker"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I needed the &lt;code>replace-response&lt;/code> module. Since I run Caddy via Docker, the best approach was to create a custom Docker image using a multi-stage build. Here is the &lt;code>Dockerfile&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-Dockerfile" data-lang="Dockerfile">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Use the official Caddy builder image&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="s"> caddy:2-builder AS builder&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># Build Caddy with the desired external module&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">RUN&lt;/span> xcaddy build &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --with github.com/caddyserver/replace-response&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># Switch to the standard Caddy runtime image&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="s"> caddy:2&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># Replace the default binary with the custom-built one&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">COPY&lt;/span> --from&lt;span class="o">=&lt;/span>builder /usr/bin/caddy /usr/bin/caddy&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Run &lt;code>docker build -t my-caddy .&lt;/code> to build the image. You will then have a &lt;code>my-caddy&lt;/code> image that includes the &lt;code>replace-response&lt;/code> functionality.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>By following these steps, we successfully added a custom module to Caddy. Using a Docker multi-stage build is an efficient way to manage dependencies and ensures that your custom Caddy environment remains consistent across different deployments.&lt;/p>
&lt;h2 id="resources">
&lt;a class="heading-anchor-link" href="#resources">Resources&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="resources"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://caddyserver.com/docs/modules/" target="_blank" rel="noopener">Caddy Documentation: Modules&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>How to Delete All Photos from Google Photos</title><link>https://en.1991421.cn/2025/09/19/how-to-delete-all-photos-from-google-photo/</link><pubDate>Fri, 19 Sep 2025 09:20:10 +0800</pubDate><guid>https://en.1991421.cn/2025/09/19/how-to-delete-all-photos-from-google-photo/</guid><description>&lt;blockquote>
&lt;p>Google Photos only offers 15GB of free storage, after which you need to pay for a subscription. I decided to migrate my photos to a domestic cloud service—Quark Netdisk. Once the migration was complete, I needed to delete the photos from Google to free up space, especially since full storage can prevent Gmail from working properly. Unfortunately, Google doesn&amp;rsquo;t provide a &amp;ldquo;Delete All&amp;rdquo; button, and manual deletion is painfully slow. Here’s how I automated the process.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-09-19-093046.jpeg"
alt="Google Photos Storage Limit"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="why-delete">
&lt;a class="heading-anchor-link" href="#why-delete">Why Delete?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-delete"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As an Alibaba 88VIP member, I get 6TB of space on Quark Netdisk, so there&amp;rsquo;s no reason for me to pay for extra Google storage. Because Google&amp;rsquo;s 15GB limit is shared across Gmail, Google Drive, and Google Photos, my photo backup was starting to affect my ability to receive emails.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-09-19-093730.jpeg"
alt="Google Storage Usage"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="steps-to-automate-deletion">
&lt;a class="heading-anchor-link" href="#steps-to-automate-deletion">Steps to Automate Deletion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="steps-to-automate-deletion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Log in to &lt;a href="https://photos.google.com/" target="_blank" rel="noopener">Google Photos&lt;/a>.&lt;/li>
&lt;li>Open the browser&amp;rsquo;s &lt;strong>Developer Console&lt;/strong> (usually F12 or Right-click &amp;gt; Inspect &amp;gt; Console).&lt;/li>
&lt;li>Access this script: &lt;a href="https://raw.githubusercontent.com/mrishab/google-photos-delete-tool/refs/heads/master/delete_photos.js" target="_blank" rel="noopener">delete_photos.js&lt;/a> and copy the entire content to your clipboard.
&lt;ul>
&lt;li>This script acts as an automated timer to find and click the delete buttons for you.&lt;/li>
&lt;li>If you don&amp;rsquo;t want to delete &lt;em>everything&lt;/em> but only a specific number of images, you can modify the &lt;code>maxImageCount&lt;/code> variable in the script before running it.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Paste the script into the Console and press &lt;strong>Enter&lt;/strong>. Be patient as it works through your library. The script will print its progress in the console.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-09-19-093347.jpeg"
alt="Running the Deletion Script"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>This method allows you to clear out your entire library. If you have a massive number of photos, you might need to leave the tab open for a while or refresh and re-run the script if it stalls.&lt;/li>
&lt;li>Remember that deleted photos go to the &lt;strong>Trash&lt;/strong> first and will still take up space until the Trash is emptied or 60 days pass. You may want to manually empty the Trash if you need to free up Gmail space immediately.&lt;/li>
&lt;/ol></description></item><item><title>My Data &amp; Cloud Sync Solution</title><link>https://en.1991421.cn/2025/09/07/my-data-sync-solution/</link><pubDate>Sun, 07 Sep 2025 21:29:22 +0800</pubDate><guid>https://en.1991421.cn/2025/09/07/my-data-sync-solution/</guid><description>&lt;blockquote>
&lt;p>There are many cloud sync solutions available, such as iCloud, Google Photos, Baidu Netdisk, or even building your own NAS. After experimenting with various options, I’ve settled on the following setup. Here it is for your reference.&lt;/p>
&lt;/blockquote>
&lt;h2 id="apple-icloud">
&lt;a class="heading-anchor-link" href="#apple-icloud">Apple iCloud&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-icloud"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I am currently subscribed to the 200GB plan. By using Family Sharing, everyone in the household can access this shared storage. It’s mainly used for full device backups and storing a portion of my photos. So far, it’s been more than enough.&lt;/p>
&lt;h2 id="quark-netdisk">
&lt;a class="heading-anchor-link" href="#quark-netdisk">Quark Netdisk&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="quark-netdisk"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I have an active Alibaba 88VIP membership, which includes a 6TB Quark Netdisk benefit. I use the Quark app on my phone to sync and store high-resolution photo albums. If my phone or iCloud storage runs low, I can safely delete local files, knowing that Quark serves as a full-scale backup for all my data.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-09-07-214000.jpeg"
alt="My Data Sync Solution - Image 1"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="dropbox">
&lt;a class="heading-anchor-link" href="#dropbox">Dropbox&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="dropbox"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I’m using the free tier (2GB), which primarily handles my Alfred preferences and configuration sync. It works perfectly for this specific purpose.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-09-07-213720.jpeg"
alt="My Data Sync Solution - Image 2"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="deprecated-solutions">
&lt;a class="heading-anchor-link" href="#deprecated-solutions">Deprecated Solutions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="deprecated-solutions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="google-photos">
&lt;a class="heading-anchor-link" href="#google-photos">Google Photos&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="google-photos"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Since Google ended its unlimited storage offering, the 15GB free tier is too restrictive for me, and I’m not currently looking to pay for an upgrade there.&lt;/p>
&lt;h3 id="nas">
&lt;a class="heading-anchor-link" href="#nas">NAS&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="nas"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I still use my NAS, but no longer as a primary sync solution for photos or documents. It now functions solely as a home media center and a destination for Mac Time Machine backups.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>This is my current setup. While it may evolve in the future, it meets all my requirements for now.&lt;/p></description></item><item><title>Talking About Spotify and Domestic Music Services</title><link>https://en.1991421.cn/2025/08/18/spotify-vs-chinese-music-services/</link><pubDate>Mon, 18 Aug 2025 18:10:36 +0800</pubDate><guid>https://en.1991421.cn/2025/08/18/spotify-vs-chinese-music-services/</guid><description>&lt;blockquote>
&lt;p>Spotify is a well-known music streaming app that I&amp;rsquo;ve been using for many years. I really like it, so here I&amp;rsquo;ll share the pros and cons. I also recommend it to users who can access it.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-08-18-183525.jpeg"
alt="https://static.1991421.cn/2025/2025-08-18-183525.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Visual design. Beauty is important. Spotify belongs to those apps that look beautiful no matter how you view them. The interface design is first-class. Similar beautiful apps include Fantastical/Things, all of which are Top1 in their respective fields.&lt;/li>
&lt;li>Interactive experience, very comfortable.&lt;/li>
&lt;li>Relatively complete Chinese music library. Foreign apps generally have incomplete Chinese music libraries, but Spotify&amp;rsquo;s Chinese music library is relatively more complete.&lt;/li>
&lt;li>Device switching experience.&lt;/li>
&lt;/ol>
&lt;h2 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Chinese lyrics don&amp;rsquo;t support Simplified Chinese. You can get used to it, but it would be great if it could support it.&lt;/li>
&lt;/ul>
&lt;h2 id="domestic-music-services">
&lt;a class="heading-anchor-link" href="#domestic-music-services">Domestic Music Services&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="domestic-music-services"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When repeatedly choosing music streaming apps, I&amp;rsquo;ve also tried the following apps and eventually gave up on them all.&lt;/p>
&lt;ul>
&lt;li>NetEase Cloud Music: I used to really like it, but now it has too much social attributes and copyright issues, so I gave up&lt;/li>
&lt;li>QQ Music: Heavy social attributes, and even as a member there are still ads which is intolerable. It&amp;rsquo;s rogue behavior. Besides, when listening to music, it defaults to showing MVs, live streams, etc. I really admire the product manager. Won&amp;rsquo;t consider it anymore&lt;/li>
&lt;li>Apple Music: Song search is too painful. For example, Chinese artist names can&amp;rsquo;t always be found, you have to switch to English names, but not everyone knows all the names. Of course there are other issues like incomplete lyrics, so I gave up&lt;/li>
&lt;li>YouTube Music: Song search and lyrics also have a bunch of issues, gave up.&lt;/li>
&lt;/ul>
&lt;p>It has to be said that in the 21st century, finding a usable music streaming app is still difficult. Currently, Spotify seems to be the relatively optimal solution.&lt;/p>
&lt;h2 id="spotify-freepremium">
&lt;a class="heading-anchor-link" href="#spotify-freepremium">Spotify Free/Premium&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="spotify-freepremium"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>There are a few things to note when using Spotify&lt;/p>
&lt;ul>
&lt;li>In Profile, you can modify region settings, but the prerequisite is that you haven&amp;rsquo;t activated Premium subscription yet.&lt;/li>
&lt;li>iOS Spotify can set language independently, unrelated to system language settings.&lt;/li>
&lt;li>New registered accounts will get more than ten days of limited premium service for free, then return to free status with ads.&lt;/li>
&lt;li>Music streaming is free but features are limited. If you want the full experience, you need to pay. I don&amp;rsquo;t reject quality services with reasonable prices, so this is acceptable. Spotify subscription payment is relatively troublesome, recommend going through group buying.&lt;/li>
&lt;/ul>
&lt;h2 id="final-words">
&lt;a class="heading-anchor-link" href="#final-words">Final Words&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-words"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Popularity has its reasons, everyone can try this service.&lt;/p></description></item><item><title>Ethers.js Research</title><link>https://en.1991421.cn/2025/08/05/ethers-js-research/</link><pubDate>Tue, 05 Aug 2025 14:40:05 +0800</pubDate><guid>https://en.1991421.cn/2025/08/05/ethers-js-research/</guid><description>&lt;blockquote>
&lt;p>Recently, an open source project needed to implement a web3.js library, so I researched the leading web3.js library - ethers.js.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-08-06-140751.jpeg"
alt="https://static.1991421.cn/2025/2025-08-06-140751.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="code-size">
&lt;a class="heading-anchor-link" href="#code-size">Code Size&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="code-size"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The source code is written in TypeScript, with actual code size around &lt;code>90k&lt;/code> lines.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-08-05-145322.jpeg"
alt="https://static.1991421.cn/2025/2025-08-05-145322.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="cross-platform-support">
&lt;a class="heading-anchor-link" href="#cross-platform-support">Cross-Platform Support&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cross-platform-support"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>ethers.js outputs both &lt;code>ES&lt;/code> and &lt;code>CJS&lt;/code> compliant code, therefore &lt;code>supporting both Browser and server-side Node.js&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">- lib.commonjs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- lib.esm
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="features">
&lt;a class="heading-anchor-link" href="#features">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Wallet management (Wallet)&lt;/li>
&lt;li>Ethereum node interaction (Provider)&lt;/li>
&lt;li>Smart contract interaction (Contract)&lt;/li>
&lt;li>Transaction processing&lt;/li>
&lt;li>Utility and helper functions&lt;/li>
&lt;li>Support for multiple Ethereum-compatible chains&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">
&lt;a class="heading-anchor-link" href="#architecture">Architecture&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="architecture"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>ethers.js is a modular library that includes the following modules:&lt;/p>
&lt;h2 id="1-abi-module-srctsabi">
&lt;a class="heading-anchor-link" href="#1-abi-module-srctsabi">1. ABI Module (&lt;code>src.ts/abi&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="1-abi-module-srctsabi"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Handle Ethereum Application Binary Interface (ABI)&lt;/p>
&lt;ul>
&lt;li>&lt;code>abi-coder.ts&lt;/code>: &lt;code>AbiCoder&lt;/code> class, responsible for ABI encoding/decoding&lt;/li>
&lt;li>&lt;code>interface.ts&lt;/code>: &lt;code>Interface&lt;/code> class, parse contract ABI, handle function calls and events&lt;/li>
&lt;li>&lt;code>fragments.ts&lt;/code>: Define ABI fragment types (functions, events, errors, etc.)&lt;/li>
&lt;li>&lt;code>coders/&lt;/code>: Various data type encoders/decoders&lt;/li>
&lt;/ul>
&lt;h2 id="2-address-module-srctsaddress">
&lt;a class="heading-anchor-link" href="#2-address-module-srctsaddress">2. Address Module (&lt;code>src.ts/address&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2-address-module-srctsaddress"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Handle Ethereum address-related operations&lt;/p>
&lt;ul>
&lt;li>Address validation and formatting&lt;/li>
&lt;li>Contract address calculation (CREATE, CREATE2)&lt;/li>
&lt;li>ICAP address format support&lt;/li>
&lt;/ul>
&lt;h2 id="4-contract-module-srctscontract">
&lt;a class="heading-anchor-link" href="#4-contract-module-srctscontract">4. Contract Module (&lt;code>src.ts/contract&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="4-contract-module-srctscontract"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Smart contract interaction&lt;/p>
&lt;ul>
&lt;li>&lt;code>contract.ts&lt;/code>: &lt;code>Contract&lt;/code> class, provides contract method call interface&lt;/li>
&lt;li>&lt;code>factory.ts&lt;/code>: Contract deployment factory&lt;/li>
&lt;li>&lt;code>wrappers.ts&lt;/code>: Event log and transaction receipt wrapper classes&lt;/li>
&lt;/ul>
&lt;h2 id="5-cryptography-module-srctscrypto">
&lt;a class="heading-anchor-link" href="#5-cryptography-module-srctscrypto">5. Cryptography Module (&lt;code>src.ts/crypto&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="5-cryptography-module-srctscrypto"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Cryptographic primitives and key management&lt;/p>
&lt;ul>
&lt;li>&lt;code>signing-key.ts&lt;/code>: &lt;code>SigningKey&lt;/code> class, elliptic curve key operations&lt;/li>
&lt;li>&lt;code>signature.ts&lt;/code>: Digital signature processing&lt;/li>
&lt;li>&lt;code>keccak.ts&lt;/code>, &lt;code>sha2.ts&lt;/code> etc.: Hash functions&lt;/li>
&lt;li>&lt;code>scrypt.ts&lt;/code>, &lt;code>pbkdf2.ts&lt;/code>: Key derivation functions&lt;/li>
&lt;/ul>
&lt;h2 id="6-hash-module-srctshash">
&lt;a class="heading-anchor-link" href="#6-hash-module-srctshash">6. Hash Module (&lt;code>src.ts/hash&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="6-hash-module-srctshash"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Various hashing and encoding operations&lt;/p>
&lt;ul>
&lt;li>&lt;code>id.ts&lt;/code>: String to hash conversion&lt;/li>
&lt;li>&lt;code>message.ts&lt;/code>: Message signing and verification&lt;/li>
&lt;li>&lt;code>typed-data.ts&lt;/code>: EIP-712 typed data signing&lt;/li>
&lt;li>&lt;code>namehash.ts&lt;/code>: ENS domain name hashing&lt;/li>
&lt;/ul>
&lt;h2 id="7-provider-module-srctsproviders">
&lt;a class="heading-anchor-link" href="#7-provider-module-srctsproviders">7. Provider Module (&lt;code>src.ts/providers&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="7-provider-module-srctsproviders"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Blockchain network connection and data retrieval&lt;/p>
&lt;ul>
&lt;li>&lt;code>abstract-provider.ts&lt;/code>: &lt;code>AbstractProvider&lt;/code> base class&lt;/li>
&lt;li>&lt;code>provider-jsonrpc.ts&lt;/code>: JSON-RPC provider&lt;/li>
&lt;li>Various third-party blockchain node service providers (Infura, Alchemy, etc.)&lt;/li>
&lt;/ul>
&lt;h2 id="8-transaction-module-srctstransaction">
&lt;a class="heading-anchor-link" href="#8-transaction-module-srctstransaction">8. Transaction Module (&lt;code>src.ts/transaction&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="8-transaction-module-srctstransaction"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Transaction creation, signing, and serialization&lt;/p>
&lt;ul>
&lt;li>&lt;code>transaction.ts&lt;/code>: &lt;code>Transaction&lt;/code> class&lt;/li>
&lt;li>&lt;code>address.ts&lt;/code>: Address-related utility functions&lt;/li>
&lt;/ul>
&lt;h2 id="9-utilities-module-srctsutils">
&lt;a class="heading-anchor-link" href="#9-utilities-module-srctsutils">9. Utilities Module (&lt;code>src.ts/utils&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="9-utilities-module-srctsutils"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Common utility functions&lt;/p>
&lt;ul>
&lt;li>&lt;code>data.ts&lt;/code>: Byte data processing&lt;/li>
&lt;li>&lt;code>errors.ts&lt;/code>: Error handling&lt;/li>
&lt;li>&lt;code>fetch.ts&lt;/code>: HTTP request wrapper&lt;/li>
&lt;li>&lt;code>maths.ts&lt;/code>: Mathematical operations&lt;/li>
&lt;li>&lt;code>utf8.ts&lt;/code>: UTF-8 encoding/decoding&lt;/li>
&lt;/ul>
&lt;h2 id="10-wallet-module-srctswallet">
&lt;a class="heading-anchor-link" href="#10-wallet-module-srctswallet">10. Wallet Module (&lt;code>src.ts/wallet&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="10-wallet-module-srctswallet"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Wallet management and key storage&lt;/p>
&lt;ul>
&lt;li>&lt;code>wallet.ts&lt;/code>: &lt;code>Wallet&lt;/code> class&lt;/li>
&lt;li>&lt;code>hdwallet.ts&lt;/code>: HD wallet implementation&lt;/li>
&lt;li>&lt;code>json-keystore.ts&lt;/code>: Keystore format support&lt;/li>
&lt;li>&lt;code>mnemonic.ts&lt;/code>: Mnemonic phrase processing&lt;/li>
&lt;/ul>
&lt;h2 id="11-wordlists-module-srctswordlists">
&lt;a class="heading-anchor-link" href="#11-wordlists-module-srctswordlists">11. Wordlists Module (&lt;code>src.ts/wordlists&lt;/code>)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="11-wordlists-module-srctswordlists"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Responsibility&lt;/strong>: Mnemonic wordlists&lt;/p>
&lt;ul>
&lt;li>Support for multilingual mnemonics&lt;/li>
&lt;/ul>
&lt;p>This modular design gives ethers.js clear separation of concerns, with each module focusing on specific functional areas, making it easy to maintain and extend.&lt;/p>
&lt;h2 id="relationship-between-ethersjs-and-metamask-wallet">
&lt;a class="heading-anchor-link" href="#relationship-between-ethersjs-and-metamask-wallet">Relationship between ethers.js and MetaMask wallet&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="relationship-between-ethersjs-and-metamask-wallet"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Standardized interfaces: Both follow Ethereum standards like EIP-1193&lt;/li>
&lt;li>Separation of responsibilities:
&lt;ul>
&lt;li>MetaMask: Private key management, user authorization, transaction signing&lt;/li>
&lt;li>ethers.js: Data formatting, ABI encoding/decoding, network communication&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Interchangeability: ethers.js can also work with other wallets (like WalletConnect)&lt;/li>
&lt;/ul>
&lt;p>MetaMask provides low-level primitive interfaces without any abstraction. While ethers.js provides higher-level abstractions and wrappers, making it more convenient for developers to interact with the Ethereum network.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-08-06-171143.jpeg"
alt="https://static.1991421.cn/2025/2025-08-06-171143.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="additional-concept-introduction">
&lt;a class="heading-anchor-link" href="#additional-concept-introduction">Additional Concept Introduction&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="additional-concept-introduction"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="smart-contracts">
&lt;a class="heading-anchor-link" href="#smart-contracts">Smart Contracts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="smart-contracts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>This name is indeed somewhat exaggerated, but it emphasizes several key characteristics:&lt;/p>
&lt;ul>
&lt;li>Automated execution&lt;/li>
&lt;li>Reduced human intervention&lt;/li>
&lt;li>Transparent and verifiable&lt;/li>
&lt;li>Reduced trust costs&lt;/li>
&lt;/ul>
&lt;h2 id="related-documentation">
&lt;a class="heading-anchor-link" href="#related-documentation">Related Documentation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documentation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://blog.chainsafe.io/web3-js-sunset/" target="_blank" rel="noopener">https://blog.chainsafe.io/web3-js-sunset/&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ethereum.org/en/developers/docs/apis/json-rpc/" target="_blank" rel="noopener">https://ethereum.org/en/developers/docs/apis/json-rpc/&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://eips.ethereum.org/EIPS/eip-6963" target="_blank" rel="noopener">https://eips.ethereum.org/EIPS/eip-6963&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://eips.ethereum.org/all" target="_blank" rel="noopener">https://eips.ethereum.org/all&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://docs.metamask.io/services/reference/ethereum/json-rpc-methods/eth_chainid/" target="_blank" rel="noopener">https://docs.metamask.io/services/reference/ethereum/json-rpc-methods/eth_chainid/&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Methods for Screen Mirroring Mobile Devices to TV and Personal Usage Experience</title><link>https://en.1991421.cn/2025/08/02/mobile-screen-mirroring-to-tv/</link><pubDate>Sat, 02 Aug 2025 21:30:00 +0800</pubDate><guid>https://en.1991421.cn/2025/08/02/mobile-screen-mirroring-to-tv/</guid><description>&lt;blockquote>
&lt;p>Recently, family members asked how to mirror their phones to the TV. It seems many people still don&amp;rsquo;t know about this feature, so I&amp;rsquo;ll introduce various methods for mirroring mobile devices to TV and share my personal usage experience.&lt;/p>
&lt;/blockquote>
&lt;h2 id="my-own-setup">
&lt;a class="heading-anchor-link" href="#my-own-setup">My Own Setup&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-own-setup"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Let me first talk about my own device situation.&lt;/p>
&lt;ol>
&lt;li>Apple TV
&lt;ul>
&lt;li>Currently have the 5th generation, considering upgrading when the new one comes out this year.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Philips TV
&lt;ul>
&lt;li>Limited by budget constraints, haven&amp;rsquo;t upgraded to Sony yet. If buying a new TV, I would definitely &lt;code>recommend Sony&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>Current TVs generally come with smart systems (with heavy bloatware characteristics) that support wireless screen mirroring. Since I&amp;rsquo;m in the Apple ecosystem and Philips&amp;rsquo; mirroring experience is quite uncomfortable, I use Apple TV as my main device for screen mirroring.&lt;/p>
&lt;h3 id="daily-usage-scenarios">
&lt;a class="heading-anchor-link" href="#daily-usage-scenarios">Daily Usage Scenarios&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="daily-usage-scenarios"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>When mirroring Apple ecosystem devices like iPhone or iPad, whether it&amp;rsquo;s mirroring or specific media like Youku videos, I simply select AirPlay, choose Apple TV, and both the TV and box automatically activate and enter mirroring mode. Mac works the same way, so sometimes I open Quark Cloud Drive on Mac to play resources, then AirPlay directly to ATV.&lt;/li>
&lt;/ol>
&lt;p>It&amp;rsquo;s that simple. If Android devices need to mirror to Apple TV, third-party apps are required. In that scenario, I directly use the TV&amp;rsquo;s smart system for mirroring since it&amp;rsquo;s also an Android system.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-08-02-231830.jpg"
alt="https://static.1991421.cn/2025/2025-08-02-231830.jpg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="common-screen-mirroring-methods">
&lt;a class="heading-anchor-link" href="#common-screen-mirroring-methods">Common Screen Mirroring Methods&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-screen-mirroring-methods"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The above covers my personal devices and usage scenarios. Below I&amp;rsquo;ll introduce common mirroring methods, including non-Apple devices/ecosystems. Technically, there are 2 mirroring solutions.&lt;/p>
&lt;ol>
&lt;li>Wireless mirroring, such as using Xiaomi Box, Apple TV, or the TV&amp;rsquo;s built-in wireless mirroring function (TVs like Hisense, Huawei, etc. all support this).&lt;/li>
&lt;li>Wired mirroring, as long as the TV supports HDMI or Type-C interfaces, phones can connect to TV via data cable. For example, iPhone can connect to TV through Lightning to HDMI cable.&lt;/li>
&lt;/ol>
&lt;p>Note: Both HDMI/Type-C support audio and video transmission, only the ancient VGA interface doesn&amp;rsquo;t support audio transmission.&lt;/p>
&lt;h2 id="what-if-traditional-tvs-dont-support-mirroring-or-have-poor-mirroring-support">
&lt;a class="heading-anchor-link" href="#what-if-traditional-tvs-dont-support-mirroring-or-have-poor-mirroring-support">What if Traditional TVs Don&amp;rsquo;t Support Mirroring or Have Poor Mirroring Support?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-if-traditional-tvs-dont-support-mirroring-or-have-poor-mirroring-support"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Replace the TV. For example, if you have a Huawei phone, purchasing a Huawei TV would naturally provide the best integrated experience. The same logic applies if you have a Xiaomi phone and buy a Xiaomi TV.&lt;/li>
&lt;li>If you don&amp;rsquo;t want to go the TV route, you can solve this with TV boxes like Xiaomi Box, Tmall Magic Box, Apple TV box, etc.&lt;/li>
&lt;/ol>
&lt;h2 id="movie-watching-approach---screen-mirroring">
&lt;a class="heading-anchor-link" href="#movie-watching-approach---screen-mirroring">Movie Watching Approach - Screen Mirroring&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="movie-watching-approach---screen-mirroring"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since screen mirroring can cast device resources, daily movie watching becomes more flexible. Here&amp;rsquo;s my commonly used approach:&lt;/p>
&lt;ol>
&lt;li>Add and save resources to Quark Cloud Drive&lt;/li>
&lt;li>Play videos from Quark Cloud Drive, wirelessly mirror to Apple TV.&lt;/li>
&lt;/ol>
&lt;p>This eliminates the need to download resources.&lt;/p>
&lt;p>Note: I recommend Taobao 88VIP, which includes Quark Cloud Drive membership, solving speed and storage capacity issues.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Device screen mirroring to TV is a common need, and I recommend everyone give it a try.&lt;/p></description></item><item><title>Getting the Redmi Note 13 5G: A Sub-$1000 Phone with Many Issues, But What More Can You Ask For?</title><link>https://en.1991421.cn/2025/07/14/buy-redmi-note13-5g/</link><pubDate>Mon, 14 Jul 2025 09:28:57 +0800</pubDate><guid>https://en.1991421.cn/2025/07/14/buy-redmi-note13-5g/</guid><description>&lt;blockquote>
&lt;p>Recently, a family member&amp;rsquo;s phone became too outdated, so we decided to get a new one. Since she was previously using a Redmi Note series phone, I chose to stick with a relatively newer model from the same Redmi Note lineup. Staying with the same brand means she can continue with familiar system usage habits without additional learning costs.&lt;/p>
&lt;/blockquote>
&lt;h2 id="note-13-or-14">
&lt;a class="heading-anchor-link" href="#note-13-or-14">Note 13 or 14?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="note-13-or-14"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>The current Redmi Note series has reached the &lt;code>14&lt;/code> model.&lt;/li>
&lt;li>In principle, buy new rather than old, just make choices based on cost considerations.&lt;/li>
&lt;/ul>
&lt;p>Here I chose the &lt;code>256GB&lt;/code> version. The 14 costs around 1,000 yuan, which I felt was too expensive, so I downgraded to the 13. After all, upgrading from 13 to 17 in the future is no different from upgrading from 14 to 18.
With national subsidies, the &lt;code>8GB+256GB Midnight Black 5G phone&lt;/code> ultimately cost &lt;code>849.51&lt;/code> CNY.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-07-22-163629.jpeg"
alt="https://static.1991421.cn/2025/2025-07-22-163629.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;blockquote>
&lt;p>For target users who aren&amp;rsquo;t sensitive to new vs. old models but are budget-conscious, I personally think there&amp;rsquo;s no need to pursue the latest model.&lt;/p>
&lt;/blockquote>
&lt;h2 id="phone-accessories">
&lt;a class="heading-anchor-link" href="#phone-accessories">Phone Accessories&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="phone-accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>It comes with a &lt;code>bundled protective case&lt;/code>, which has decent quality. No need to buy another case for now.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-07-20-235327.jpeg"
alt="https://static.1991421.cn/2025/2025-07-20-235327.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/li>
&lt;li>The bundled screen protector is &lt;code>not good&lt;/code>, poor quality, so you need to buy a separate one. I bought the following style:
&lt;ul>
&lt;li>Flashmo Compatible with Redmi Note13 Pro Tempered Glass Screen Protector Note13 [Enhanced Double Anti-Fingerprint] 2-pack, priced at &lt;code>18 CNY&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>Besides these, I haven&amp;rsquo;t purchased any other accessories currently.&lt;/p>
&lt;h2 id="user-experience">
&lt;a class="heading-anchor-link" href="#user-experience">User Experience&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="user-experience"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After using it for several days, I think this phone has the following pros and cons:&lt;/p>
&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Build Quality&lt;/strong>: For a phone in the &lt;code>sub-1000 yuan&lt;/code> price range, I think the build quality is good enough, and it&amp;rsquo;s quite light at &lt;code>187g&lt;/code>. It&amp;rsquo;s slightly lighter than my iPhone 16 Pro, which I find heavy when using with a case.&lt;/li>
&lt;li>&lt;strong>Battery Life&lt;/strong>: It can easily last 1 day or 1.5 days of actual use, thanks to the &lt;code>5000 mAh&lt;/code> battery.
&lt;ul>
&lt;li>In comparison, the iPhone 16 Pro only has &lt;code>3582mAh&lt;/code>. The saying &amp;ldquo;only iPhone users have battery anxiety&amp;rdquo; really makes sense.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Volume&lt;/strong>: I think it&amp;rsquo;s loud enough. At least family members say the music volume is loud, and the audio quality is decent. If family members want better audio quality when listening to music outdoors, besides the phone itself, they can choose to buy a JBL Bluetooth speaker, which only costs around 100 yuan.&lt;/li>
&lt;/ol>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>&lt;strong>Camera Quality&lt;/strong>: The rear camera photography is quite average, but considering the price point, it&amp;rsquo;s understandable. However, the advertised &lt;code>100 megapixels&lt;/code> feels deceptive when you look back at the image quality, especially since even iPhones don&amp;rsquo;t have such high pixel counts.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Pre-installed Software&lt;/strong>: After turning on the phone, I found a &lt;code>screen full of apps&lt;/code> - it&amp;rsquo;s like buying a phone and getting a bunch of apps for free. Fortunately, most can be uninstalled, but it takes time to clean up. For elderly users who don&amp;rsquo;t know how to delete them, they might face issues like storage occupation, data consumption, and potential scams.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-07-22-210600.jpeg"
alt="https://static.1991421.cn/2025/2025-07-22-210600.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>These two shortcomings are common issues among most domestic manufacturers. They want to reduce prices while maintaining profits, so they compromise in these areas.&lt;/p>
&lt;h2 id="additional-information">
&lt;a class="heading-anchor-link" href="#additional-information">Additional Information&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="additional-information"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Let me supplement some information about whether this phone supports certain features to avoid confusion.&lt;/p>
&lt;h3 id="wireless-charging">
&lt;a class="heading-anchor-link" href="#wireless-charging">Wireless Charging&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wireless-charging"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Redmi Note does &lt;code>not support wireless charging&lt;/code>.&lt;/p>
&lt;h3 id="sd-card">
&lt;a class="heading-anchor-link" href="#sd-card">SD Card&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="sd-card"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Redmi Note series phones &lt;code>support SD card storage expansion&lt;/code>.&lt;/p>
&lt;h3 id="xiaomi-hyperos">
&lt;a class="heading-anchor-link" href="#xiaomi-hyperos">Xiaomi HyperOS&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xiaomi-hyperos"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The phone &lt;code>supports upgrading to HyperOS&lt;/code>. From my brief usage, I don&amp;rsquo;t notice much difference from the previous system except for cosmetic changes - I&amp;rsquo;d need deeper usage to feel the differences.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>These are my genuine experiences using the Redmi Note 13. Overall, for a sub-1000 yuan phone, meeting basic usage needs is sufficient.&lt;/p>
&lt;p>&lt;strong>Suitable Users&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>Users with low phone requirements&lt;/li>
&lt;li>Budget-conscious users&lt;/li>
&lt;li>Elderly family members or backup phone needs&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Purchase Recommendations&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>If you prioritize camera experience, consider increasing your budget for other models&lt;/li>
&lt;li>Remember to clean up pre-installed software after purchase&lt;/li>
&lt;/ul></description></item><item><title>Anker Power Bank Recall - I Finally Chose Self-Disposal and Selected Replacement</title><link>https://en.1991421.cn/2025/07/10/anker-charger-recall/</link><pubDate>Thu, 10 Jul 2025 12:05:28 +0800</pubDate><guid>https://en.1991421.cn/2025/07/10/anker-charger-recall/</guid><description>&lt;blockquote>
&lt;p>Both of my Anker power banks were in the recall batch. I recently received a text message suggesting self-disposal, so I decided to follow the recommendation. Here I&amp;rsquo;m documenting the process.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-07-10-121019.jpeg"
alt="https://static.1991421.cn/2025/2025-07-10-121019.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="self-disposal-steps">
&lt;a class="heading-anchor-link" href="#self-disposal-steps">Self-Disposal Steps&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="self-disposal-steps"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>For self-disposal, the steps are as follows. It&amp;rsquo;s actually not too troublesome - treat it as a fun activity.&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>‌Salt Water Preparation‌: Use 5%-10% concentration salt water (regular table salt mixed with clean water in proportion).
&lt;ul>
&lt;li>I personally think it doesn&amp;rsquo;t need to be too strict; approximately this ratio is fine.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>‌Soaking Process‌: Completely submerge the power bank in salt water for 24 hours.
&lt;ul>
&lt;li>I put it in the night before and took it out the next evening.&lt;/li>
&lt;li>For safety considerations, I suggest placing it somewhere like a balcony.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>‌Evidence Submission‌: Take photos of the power bank&amp;rsquo;s SN code (unique product identifier) and soaking photos, then upload to the designated channel.
&lt;ul>
&lt;li>Just submit to the Anker recall webpage: Official WeChat account - Participate in Recall - Recall Progress, change to &amp;ldquo;Self-disposal&amp;rdquo;, then upload SN code and soaking photos.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>‌Safe Disposal‌: After soaking, drain the water and put it in a hazardous waste bag for disposal.
&lt;ul>
&lt;li>I &lt;code>haven't disposed of it yet&lt;/code>; I plan to throw away the old power bank after receiving the new one.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-07-10-121620.jpeg"
alt="https://static.1991421.cn/2025/2025-07-10-121620.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="official-self-disposal-video-tutorial">
&lt;a class="heading-anchor-link" href="#official-self-disposal-video-tutorial">Official Self-Disposal Video Tutorial&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="official-self-disposal-video-tutorial"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you still have issues understanding the steps, you can also watch Anker&amp;rsquo;s official tutorial video:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://recall.anker.com.cn/images/cn-video-1.mp4"
alt="https://recall.anker.com.cn/images/cn-video-1.mp4"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="modify-recall-method-or-benefits">
&lt;a class="heading-anchor-link" href="#modify-recall-method-or-benefits">Modify Recall Method or Benefits?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="modify-recall-method-or-benefits"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If it&amp;rsquo;s a new recall application, you can naturally choose the method you need directly, such as benefits. If you have the same situation as me, with a previously submitted recall application, you can still modify the application under the official WeChat account, such as modifying benefits or recall method. Of course, once everything is finally approved, it cannot be modified.&lt;/p>
&lt;p>As shown below, after I changed from mailing the power bank to self-disposal and changed the benefit from &amp;ldquo;refund&amp;rdquo; to &amp;ldquo;replacement&amp;rdquo;, everything has now been approved, so they&amp;rsquo;ve all become non-modifiable.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-07-10-122118.jpeg"
alt="https://static.1991421.cn/2025/2025-07-10-122118.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>·&lt;/p>
&lt;h2 id="about-self-disposing-power-banks---please-note">
&lt;a class="heading-anchor-link" href="#about-self-disposing-power-banks---please-note">About Self-Disposing Power Banks - Please Note!!!&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="about-self-disposing-power-banks---please-note"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After sharing the self-disposal process with friends, they were also eager to try disposing of their own.&lt;/p>
&lt;p>Please note: Not all brand power banks can be self-disposed with compensation. This depends on whether the brand&amp;rsquo;s recall policy for that specific model/batch supports self-disposal. For example, the above power bank qualified because it met the model/batch requirements. If it&amp;rsquo;s not within the supported range, you cannot choose self-disposal. Not all power banks can be directly destroyed for replacement.&lt;/p>
&lt;h2 id="about-compensation-plan-selection---have-power-banks-become-more-expensive">
&lt;a class="heading-anchor-link" href="#about-compensation-plan-selection---have-power-banks-become-more-expensive">About Compensation Plan Selection - Have Power Banks Become More Expensive?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="about-compensation-plan-selection---have-power-banks-become-more-expensive"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I previously chose a refund, but since I still wanted to get power banks, I searched on JD and found the prices were quite high. For example, Anker&amp;rsquo;s MagSafe 10000mAh power bank costs over 300 yuan, and wired ones aren&amp;rsquo;t cheap either. After this whole incident, it seems like everything has increased in price. As expected, consumers always end up paying the bill.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-07-10-123809.jpeg"
alt="https://static.1991421.cn/2025/2025-07-10-123809.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Considering that buying new ones would also cost money, I chose replacement for both. The specific model (A1637 3-in-1 10000mAh fast charging power bank, 3C certified, with built-in AC charging head + Type-C cable, 30W output) - the lack of wireless charging is still tolerable.&lt;/p>
&lt;h2 id="current-progress">
&lt;a class="heading-anchor-link" href="#current-progress">Current Progress&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-progress"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After uploading the screenshots following self-disposal, all reviews have now passed and no other operations can be performed. I just need to wait for the &lt;code>new shipment&lt;/code>. The current message I received is as follows:&lt;/p>
&lt;blockquote>
&lt;p>We sincerely apologize for the inconvenience! Regarding replacement processing time, it is estimated that new products will be shipped within 4-8 weeks after receiving your returned product. This is mainly due to current tight inventory supply and high demand for replacements of this product model.
If you have exceeded this timeframe, we recommend checking the recall progress through this link: &lt;a href="https://recall.anker.com.cn/progress-inquiry/" target="_blank" rel="noopener">https://recall.anker.com.cn/progress-inquiry/&lt;/a>. We will track your order throughout the process. Thank you for your patience and understanding!&lt;/p>
&lt;/blockquote>
&lt;p>This is understandable, especially with recent 3C issues causing supply shortages.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>With this, the recall process has come to an end, and I&amp;rsquo;m just waiting for Anker to send the new ones.&lt;/li>
&lt;li>After this power bank incident, it seems Anker hasn&amp;rsquo;t been greatly affected, while Romoss appears to be in a more precarious position.&lt;/li>
&lt;/ol></description></item><item><title>Everyday Magic: Three MagSafe Benefits That Change Your Routine</title><link>https://en.1991421.cn/2025/07/04/everyday-magsafe-benefits-that-make-your-iphone-smarter-and-life-simpler/</link><pubDate>Fri, 04 Jul 2025 22:52:04 +0800</pubDate><guid>https://en.1991421.cn/2025/07/04/everyday-magsafe-benefits-that-make-your-iphone-smarter-and-life-simpler/</guid><description>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-07-04-232113.jpeg"
alt="Everyday Magic: Three MagSafe Benefits That Change Your Routine - Fig 1"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>MagSafe is not just a gimmick. It truly changes how we charge iPhones and use accessories.&lt;/p>
&lt;p>What does it mean for daily life? Whether you work from home, commute around, or binge shows on the couch, MagSafe adds real convenience and makes life easier and more efficient.&lt;/p>
&lt;p>Here are three reasons MagSafe is worth recommending:&lt;/p>
&lt;ol>
&lt;li>A cleaner, more organized space&lt;/li>
&lt;li>Wireless charging anytime, anywhere&lt;/li>
&lt;li>Simplified multi-purpose accessories&lt;/li>
&lt;/ol>
&lt;p>Let us dive into each point.&lt;/p>
&lt;h2 id="1-save-space">
&lt;a class="heading-anchor-link" href="#1-save-space">1. Save space&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="1-save-space"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>MagSafe means no more plugging and unplugging cables and no more hunting for chargers around the house. If you charge your phone before bed like I do, a MagSafe charger can quietly change how your nightstand looks.&lt;/p>
&lt;p>It reduces cable clutter and frees up space. No tangled wires, no plugs taking over outlets. Your bedroom looks cleaner and more refreshing.&lt;/p>
&lt;p>This change is not limited to the bedroom. The same applies to your home office. Put a MagSafe charger on your desk - it looks good and keeps your workspace tidy and organized.&lt;/p>
&lt;h2 id="2-wireless-charging-on-the-go">
&lt;a class="heading-anchor-link" href="#2-wireless-charging-on-the-go">2. Wireless charging on the go&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2-wireless-charging-on-the-go"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-07-04-233234.jpeg"
alt="Everyday Magic: Three MagSafe Benefits That Change Your Routine - Fig 2"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>A MagSafe power bank lets you charge easily while traveling and ditch the bulky combo of power bank plus cable. Just snap it to the back of your phone and charge while using it.&lt;/p>
&lt;p>For me, the best part is the &amp;ldquo;place and charge&amp;rdquo; experience. No repeated plugging. Just set your iPhone down, the magnets align, and it starts charging.&lt;/p>
&lt;p>Precise magnetic alignment brings another benefit: you no longer worry about the coil being misaligned. Wireless charging is a bit slower, but the convenience makes it worth it.&lt;/p>
&lt;h2 id="3-multi-purpose-stands-and-wallets">
&lt;a class="heading-anchor-link" href="#3-multi-purpose-stands-and-wallets">3. Multi-purpose stands and wallets&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="3-multi-purpose-stands-and-wallets"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If your car does not have CarPlay, a MagSafe car mount is the best navigation companion.
If you do not want to carry a separate wallet but need to carry some cards or ID, a magnetic wallet is a good option.
MagSafe&amp;rsquo;s snap-on design greatly simplifies the steps and is genuinely convenient.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>MagSafe is not just cool tech - it brings real convenience to daily life. From charging to accessories, from mounts to mobility, it makes the iPhone experience more efficient, cleaner, and more elegant.&lt;/p>
&lt;p>If you have not tried MagSafe yet, it is worth a try.&lt;/p></description></item><item><title>Japan Free Travel: Step-by-Step Trip Guide</title><link>https://en.1991421.cn/2025/06/29/japan-free-travel/</link><pubDate>Sun, 29 Jun 2025 12:24:31 +0800</pubDate><guid>https://en.1991421.cn/2025/06/29/japan-free-travel/</guid><description>&lt;blockquote>
&lt;p>My annual leave was about to expire, so I took a few days off for a trip to Japan. It was absolutely fantastic, so I wanted to document the preparation work and overall journey here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="preparation">
&lt;a class="heading-anchor-link" href="#preparation">Preparation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="preparation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;code>Japan Visa&lt;/code>: I went through Ctrip for processing and chose the 3-year visa. Since all my documents were complete, it was very smooth with no issues. I&amp;rsquo;d recommend choosing Ctrip&amp;rsquo;s self-operated service.&lt;/li>
&lt;li>&lt;code>Japanese Yen Cash&lt;/code>: For 2 people over 6 days, I exchanged 50,000 yen, and found I still had 15,000 left when I returned home. I recommend exchanging cash in advance since some merchants are cash-only.&lt;/li>
&lt;li>&lt;code>Visit Japan Web Online Declaration&lt;/code>: Register and declare in advance. You can also queue up to declare after entering Japan, but doing it beforehand is more efficient.&lt;/li>
&lt;li>&lt;code>General Planning&lt;/code>: Japan isn&amp;rsquo;t exactly cheap for things like accommodation, transportation, and dining. Personally, I think it&amp;rsquo;s a bit more expensive compared to Beijing, so having a plan helps keep everything under control.&lt;/li>
&lt;li>&lt;code>Mobile Data Card&lt;/code>: You can buy one directly on Taobao. I got a 7-day 15GB plan and didn&amp;rsquo;t use it all up, but better safe than sorry.&lt;/li>
&lt;li>&lt;code>Suica Card&lt;/code>: For iPhone users, you can add a Japanese Suica card in advance. You can use it to pay directly on many routes in Japan.&lt;/li>
&lt;li>&lt;code>JCB Credit Card&lt;/code>: Many Japanese merchants support JCB credit cards. I recommend applying for one in advance as there are activity rebates, and also bring a Visa card - having multiple payment options is safer.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Regarding the plastic bags mentioned online, I personally think it&amp;rsquo;s unnecessary. At most, carry a few with you. I brought some but barely used them. Just be careful not to litter, which should be the case domestically as well.&lt;/strong>&lt;/p>
&lt;h2 id="overall-travel-plan">
&lt;a class="heading-anchor-link" href="#overall-travel-plan">Overall Travel Plan&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="overall-travel-plan"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Our route was Beijing → Tokyo → Osaka → Beijing. Since this was our first time in Japan, we wanted to visit the major cities first. Future trips can explore different places.&lt;/p>
&lt;p>For both Tokyo and Osaka, we followed recommendations from Xiaohongshu (Little Red Book) and AI suggestions, making appropriate selections. I personally don&amp;rsquo;t recommend &amp;ldquo;commando-style&amp;rdquo; traveling - it&amp;rsquo;s no fun at all.&lt;/p>
&lt;h2 id="transportation">
&lt;a class="heading-anchor-link" href="#transportation">Transportation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="transportation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In Tokyo, I bought a Tokyo card but found I barely used it. In Osaka, I bought a tourist pass (including transportation/attractions), which felt very cost-effective.&lt;/p>
&lt;p>For navigation, I recommend using Google Maps or Apple Maps. Gaode Maps actually works too, but has obvious shortcomings like missing station times and location drift. However, for navigating in major cities, it&amp;rsquo;s adequate. This really depends on personal habits and requirements.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-29-125415.jpeg"
alt="https://static.1991421.cn/2025/2025-06-29-125415.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="accommodation">
&lt;a class="heading-anchor-link" href="#accommodation">Accommodation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accommodation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I booked accommodation through Qunar. We stayed in a hotel in Tokyo and an Airbnb in Osaka.&lt;/p>
&lt;h2 id="food">
&lt;a class="heading-anchor-link" href="#food">Food&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="food"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I personally really enjoy Japanese fish cakes and udon noodles. My wife loved the fish there - some can be eaten raw and are quite delicious.&lt;/p>
&lt;h2 id="attractions">
&lt;a class="heading-anchor-link" href="#attractions">Attractions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="attractions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Tokyo Tower&lt;/li>
&lt;li>Tokyo Skytree&lt;/li>
&lt;li>Tokyo National Museum&lt;/li>
&lt;li>Osaka - Kaiyukan Aquarium&lt;/li>
&lt;li>Osaka - Umeda Sky Building&lt;/li>
&lt;li>Osaka Castle&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Japan is wonderful and not too far from China. The cultures are similar - for example, Chinese characters make up 50% of Japanese text, so reading text isn&amp;rsquo;t actually that difficult.&lt;/p></description></item><item><title>Anker Power Bank Recall: Both of Mine Are Affected</title><link>https://en.1991421.cn/2025/06/26/anker-powerbank-recall-2025/</link><pubDate>Thu, 26 Jun 2025 22:23:51 +0800</pubDate><guid>https://en.1991421.cn/2025/06/26/anker-powerbank-recall-2025/</guid><description>&lt;blockquote>
&lt;p>I recently saw discussions about an Anker power bank recall. I followed the official guidance to check, and unexpectedly both of my Anker power banks are within the recall scope. I haven&amp;rsquo;t been through this before, so I&amp;rsquo;m documenting my recall application and key details here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="my-power-banks">
&lt;a class="heading-anchor-link" href="#my-power-banks">My Power Banks&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-power-banks"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I currently use &lt;code>3&lt;/code> power banks: two are &lt;code>Anker 10,000 mAh&lt;/code> and one is a &lt;code>Xiaomi 20,000 mAh&lt;/code>.&lt;/p>
&lt;h3 id="two-ankers">
&lt;a class="heading-anchor-link" href="#two-ankers">Two Ankers&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="two-ankers"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-26-223753.heic"
alt="https://static.1991421.cn/2025/2025-06-26-223753.heic"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="one-xiaomi">
&lt;a class="heading-anchor-link" href="#one-xiaomi">One Xiaomi&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="one-xiaomi"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;strong>The power bank on the right in the image below is the Xiaomi.&lt;/strong>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-18-212611.jpeg"
alt="https://static.1991421.cn/2025/2025-05-18-212611.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="how-to-submit-a-recall">
&lt;a class="heading-anchor-link" href="#how-to-submit-a-recall">How to Submit a Recall&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-to-submit-a-recall"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here&amp;rsquo;s how to confirm whether your unit is covered and how to submit a recall request.&lt;/p>
&lt;h3 id="find-your-model">
&lt;a class="heading-anchor-link" href="#find-your-model">Find your model&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="find-your-model"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>First confirm the exact model. You can find it on the back of the power bank, or check the order details on the platform you used to purchase it. I checked JD → Orders → Product details and confirmed my Anker units are model &lt;code>1642&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Note: Getting the exact model is the first step. If the model doesn&amp;rsquo;t match, the recall does not apply.&lt;/strong>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-26-235403.jpeg"
alt="https://static.1991421.cn/2025/2025-06-26-235403.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="recall-process-overview">
&lt;a class="heading-anchor-link" href="#recall-process-overview">Recall process overview&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="recall-process-overview"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The process has four steps:&lt;/p>
&lt;ol>
&lt;li>Submit the recall application&lt;/li>
&lt;li>Wait for Anker to mail you a protective return bag
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-26-230620.jpg"
alt="Anker protective bag"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/li>
&lt;li>Place the old power bank in the bag and return it&lt;/li>
&lt;li>Receive compensation based on the option you chose&lt;/li>
&lt;/ol>
&lt;h3 id="detailed-application-steps">
&lt;a class="heading-anchor-link" href="#detailed-application-steps">Detailed application steps&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="detailed-application-steps"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Submit your application on Anker&amp;rsquo;s recall site: &lt;a href="https://recall.anker.com.cn/recall-form/?_=1750768444099" target="_blank" rel="noopener">https://recall.anker.com.cn/recall-form/?_=1750768444099&lt;/a>&lt;/p>
&lt;p>Prepare and fill out the following:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Power bank SN&lt;/strong> (serial number)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Proof of purchase&lt;/strong> — invoice or purchase screenshot, as long as it shows the amount and product info. It&amp;rsquo;s &lt;code>not mandatory to have an invoice&lt;/code>. Mine were older purchases and reissuing invoices would be a hassle, so I used JD order detail screenshots.&lt;/p>
&lt;ul>
&lt;li>Example JD order detail screenshot:&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-26-224453.jpeg"
alt="JD order detail screenshot"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Order number&lt;/strong> — the order ID from your purchase&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Important:&lt;/strong> Units of the same model are not necessarily all covered. Anker determines recall eligibility by SN (batch). Only specific batches are included.&lt;/p>
&lt;h3 id="compensation-options">
&lt;a class="heading-anchor-link" href="#compensation-options">Compensation options&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="compensation-options"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>If your unit qualifies, Anker offers &lt;code>three&lt;/code> options:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Original purchase amount + ¥50 no‑threshold Anker Store coupon&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Full refund for the original order amount&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Free upgrade to the 3‑in‑1 power bank retailing at ¥279 (model A1637)&lt;/strong>&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>My take:&lt;/strong> I find &lt;code>Option 2 (full refund)&lt;/code> the most practical. While Option 3&amp;rsquo;s replacement has a higher retail price, the real value may not match the MSRP, and it &lt;code>does not support MagSafe wireless charging&lt;/code>. If your original power bank supports wireless charging, the replacement may not meet your needs.&lt;/p>
&lt;p>Since both of my Ankers qualify, I chose different options to try: one with Option 2 (refund) and the other with Option 3 (replacement).&lt;/p>
&lt;p>After choosing a compensation option and submitting, just wait for the protective bag and return the old unit as instructed.&lt;/p>
&lt;h2 id="background">
&lt;a class="heading-anchor-link" href="#background">Background&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="background"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="official-reason-for-the-recall">
&lt;a class="heading-anchor-link" href="#official-reason-for-the-recall">Official reason for the recall&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="official-reason-for-the-recall"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;blockquote>
&lt;p>During recent quality and safety checks, we found that a supplier changed raw materials for certain batches of industry‑standard cells without approval. This may cause, in very rare cases, separator insulation failure after long‑term cycling, leading to overheating or even combustion risks.&lt;/p>
&lt;/blockquote>
&lt;p>Notably, this is not unique to Anker. Multiple brands using cells from the same batches have issued similar recalls with essentially the same description. This indicates the issue lies with the upstream cell supplier rather than brand‑specific design or manufacturing.&lt;/p>
&lt;h3 id="latest-developments-and-impact">
&lt;a class="heading-anchor-link" href="#latest-developments-and-impact">Latest developments and impact&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="latest-developments-and-impact"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;blockquote>
&lt;p>To ensure flight safety, the Civil Aviation Administration issued an urgent notice: starting June 28, passengers are prohibited from carrying power banks on domestic flights that lack a CCC mark, have an unclear CCC mark, or belong to recalled models or batches.&lt;/p>
&lt;/blockquote>
&lt;p>Note: For models under recall, this applies regardless of whether your specific batch is listed. This rule is stricter than the brand recall scope. If you own an affected model and plan to fly, it&amp;rsquo;s best not to bring that power bank.&lt;/p>
&lt;h3 id="how-to-check-the-ccc-certification">
&lt;a class="heading-anchor-link" href="#how-to-check-the-ccc-certification">How to check the CCC certification&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-to-check-the-ccc-certification"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>You can find the CCC mark on the power bank itself. I checked mine and found one Anker without the CCC mark and the other with it. Why would big brands have units without CCC? The answer:
No CCC doesn&amp;rsquo;t necessarily mean unsafe, but under current rules such units cannot be carried on flights.&lt;/p>
&lt;blockquote>
&lt;p>CCC certification started on August 1, 2023. After a one‑year transition, from August 1, 2024 onward, related products without a CCC certificate and mark may not be shipped, sold, imported, or used in commercial activities.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-26-234030.jpeg"
alt="https://static.1991421.cn/2025/2025-06-26-234030.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="safety-recommendations">
&lt;a class="heading-anchor-link" href="#safety-recommendations">Safety recommendations&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="safety-recommendations"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>&lt;strong>Check promptly:&lt;/strong> If you have an Anker power bank, immediately check the model and SN to confirm recall eligibility. Safety first, even if it appears to work fine today.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>On brand choices:&lt;/strong> In a previous post — &lt;a href="https://1991421.cn/2025/05/17/the-best-battery-pack/" target="_blank" rel="noopener">&amp;ldquo;Real‑world experience: my current favorite power bank&amp;rdquo;&lt;/a> — I recommended Anker. While this recall is unexpected, there&amp;rsquo;s no need to write off the brand entirely. The root cause is at the upstream cell supplier and affects multiple brands, not Anker alone.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>In short, don&amp;rsquo;t ignore safety issues with electronics. I hope this helps you understand the recall and take timely steps to protect yourself.&lt;/p></description></item><item><title>As an Apple User, the 6 Features I Want Most</title><link>https://en.1991421.cn/2025/06/15/6-things-we-apple-users-desperately-want/</link><pubDate>Sun, 15 Jun 2025 23:23:36 +0800</pubDate><guid>https://en.1991421.cn/2025/06/15/6-things-we-apple-users-desperately-want/</guid><description>&lt;p>Here are six features that Apple users (at least me) desperately want—some software, some hardware.&lt;/p>
&lt;h2 id="1-iphone-landscape-mode">
&lt;a class="heading-anchor-link" href="#1-iphone-landscape-mode">1. iPhone landscape mode&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="1-iphone-landscape-mode"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://miro.medium.com/v2/1*4_9oVcS6ujpA3DFJvXWcBQ.png"
alt="Image provided by the author."
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>In 2014, the iPhone 6 Plus introduced &lt;code>landscape mode&lt;/code> to accommodate its larger display. Ironically, the iPhone 12 mini has a screen size similar to the iPhone 6. Yet today, even larger iPhone models still don’t have landscape mode. WHY? Because in iOS 14, Apple introduced home screen widgets. Keeping the icon and widget grid consistent in landscape is a tough job for iOS developers.&lt;/p>
&lt;h2 id="2-airpods-with-a-display">
&lt;a class="heading-anchor-link" href="#2-airpods-with-a-display">2. AirPods with a display&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2-airpods-with-a-display"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-12-104412.jpeg"
alt="As an Apple User, the 6 Features I Want Most - Fig 1"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>How great would it be if the case had an &lt;code>LED display&lt;/code>? It could show the current track, battery status, and more—like an iPod. Knockoff brands have sold flashy AirPods alternatives with displays for years at less than a quarter of the price. Adding a small LED probably wouldn’t raise costs much. At worst, Apple could sell a display case as an upgrade.&lt;/p>
&lt;h2 id="3-capacitive-volume-controls">
&lt;a class="heading-anchor-link" href="#3-capacitive-volume-controls">3. Capacitive volume controls&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="3-capacitive-volume-controls"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://miro.medium.com/v2/1*NiCDemiXlKETQhu_To04Aw.png"
alt="Image provided by the author."
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Apple introduced the “Action Button” in the iPhone 15 era to replace the mute switch. After using it, I realized how annoying it is—mainly because of its position.&lt;/p>
&lt;p>The Action Button is exactly where the mute switch used to be. And it’s basically a smaller version of the volume button, which makes it confusing. I often press the Action Button when I just want to raise the volume, triggering mute or AI, etc. The core issue is the Action Button is too close to the volume buttons, and both are pressable. By feel alone, you can’t tell which one you’re pressing. It also makes screenshots annoying: I should press Side + Volume Up but accidentally hit the Action Button.&lt;/p>
&lt;p>A &lt;code>capacitive volume bar&lt;/code> like the camera control key would solve this. Honestly, new iPhones have too many buttons. Since iPhone X removed the Home button, iPhone’s hardware layout has already changed dramatically.&lt;/p>
&lt;h2 id="4-macbook-with-dynamic-island">
&lt;a class="heading-anchor-link" href="#4-macbook-with-dynamic-island">4. MacBook with Dynamic Island&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="4-macbook-with-dynamic-island"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-16-220717.jpeg"
alt="As an Apple User, the 6 Features I Want Most - Fig 2"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>The MacBook notch feels as useless as the LiDAR scanner on the iPad Pro. After all, it’s already 2025 and MacBook still lacks Face ID.&lt;/p>
&lt;p>Why not replace the notch with a &lt;code>Dynamic Island&lt;/code> design? Face ID could be integrated there, and an always‑present interactive UI element at the top could further enhance macOS.&lt;/p>
&lt;h2 id="5-stylish-colorful-airtags">
&lt;a class="heading-anchor-link" href="#5-stylish-colorful-airtags">5. Stylish, colorful AirTags&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="5-stylish-colorful-airtags"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://miro.medium.com/v2/1*EZKtqZ5uHkZsUCkUhoJcKw.png"
alt="Image provided by the author."
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Right now, AirTags only come in silver/white. Compared with the vibrant colors of other Apple accessories, they feel dull. Like charging cables, it would be great if Apple offered &lt;code>multiple AirTag colors&lt;/code>.&lt;/p>
&lt;p>It would also help with organization—multiple AirTags would be easier to distinguish at a glance. Apple already sells colorful accessories like key rings, so colored AirTags make sense. It adds personality while keeping Apple’s aesthetic.&lt;/p>
&lt;p>Also, Apple won’t update AirTags every year, so keeping multiple colors likely won’t hurt production. They could adjust color production based on demand.&lt;/p>
&lt;h2 id="6-reverse-wireless-charging">
&lt;a class="heading-anchor-link" href="#6-reverse-wireless-charging">6. Reverse wireless charging&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="6-reverse-wireless-charging"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://miro.medium.com/v2/1*GasADFlV_tcvnqPnyoAZEQ.png"
alt="Image provided by the author."
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Since Apple replaced Lightning with USB‑C, carrying cables is easier. But sometimes I forget a cable, and I wish the iPhone could &lt;code>reverse‑charge&lt;/code> AirPods wirelessly. Reverse wireless charging would be extremely useful: place AirPods, Apple Watch, or even another phone on the back of the iPhone to charge. When you’re out with low battery and no charger, it would be a lifesaver.&lt;/p>
&lt;p>Although iPhone still doesn’t support this, many Android phones do. Samsung’s Galaxy S10/S20/S21/S22 series support “Wireless PowerShare.” Google Pixel 6 Pro and Pixel 7 Pro offer reverse charging too. Even OnePlus added it on devices like the OnePlus 10 Pro. So… when will Apple support it?&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>That’s it for my Apple wish list.&lt;/p></description></item><item><title>How to Download and Install iOS 26 Beta</title><link>https://en.1991421.cn/2025/06/10/how-to-download-beta-profile-ios/</link><pubDate>Tue, 10 Jun 2025 07:32:49 +0800</pubDate><guid>https://en.1991421.cn/2025/06/10/how-to-download-beta-profile-ios/</guid><description>&lt;blockquote>
&lt;p>Apple has provided official methods to download and install developer preview versions of iOS/iPadOS/macOS and other systems, eliminating the need to use third-party platforms for updates.
This article uses iPhone as an example to demonstrate how to download and install iOS 26 Beta version.&lt;/p>
&lt;/blockquote>
&lt;h2 id="important-notes">
&lt;a class="heading-anchor-link" href="#important-notes">Important Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="important-notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>It&amp;rsquo;s recommended to experience the Beta system on a &lt;code>secondary device&lt;/code>. If installing on your primary device, first connect to a Mac or other device to back up your data before upgrading. If you&amp;rsquo;re willing to take the risk directly, that&amp;rsquo;s also an option&amp;hellip;&lt;/li>
&lt;li>For primary devices, it&amp;rsquo;s recommended to perform a &lt;code>system backup&lt;/code> using a Mac or other device. If you want to revert to the stable version after upgrading, you can restore from the backup.&lt;/li>
&lt;li>iOS 26 requires &lt;code>iPhone 11&lt;/code> or newer models.&lt;/li>
&lt;/ol>
&lt;h2 id="download-developer-app">
&lt;a class="heading-anchor-link" href="#download-developer-app">Download Developer App&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="download-developer-app"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Download the official &lt;code>Developer&lt;/code> App from the App Store:
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-10-072915.jpeg"
alt="https://static.1991421.cn/2025/2025-06-10-072915.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Or directly access the download link: &lt;a href="https://apps.apple.com/cn/app/apple-developer/id640199958" target="_blank" rel="noopener">https://apps.apple.com/cn/app/apple-developer/id640199958&lt;/a>&lt;/p>
&lt;h2 id="log-in-to-developer-app">
&lt;a class="heading-anchor-link" href="#log-in-to-developer-app">Log in to Developer App&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="log-in-to-developer-app"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Sign in to the Developer App using your Apple ID:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-10-073833.jpeg"
alt="https://static.1991421.cn/2025/2025-06-10-073833.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="install-system-update">
&lt;a class="heading-anchor-link" href="#install-system-update">Install System Update&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="install-system-update"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Navigate through: Settings &amp;gt; General &amp;gt; Software Update &amp;gt; Beta Updates&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-10-073124.jpeg"
alt="https://static.1991421.cn/2025/2025-06-10-073124.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Wait for the download and installation to complete. During installation, the device requires at least 20% battery, so it&amp;rsquo;s recommended to perform this while charging.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>The installation method for Beta versions on other Apple platforms (such as macOS) is similar. It&amp;rsquo;s recommended to experience them while ensuring data security. Be careful 🚗.&lt;/li>
&lt;li>Beta versions have many bugs and receive frequent updates for a period. If you want to revert after upgrading, simply use your previous backup to restore.&lt;/li>
&lt;/ol></description></item><item><title>Build Your Private Media Library with NAS for Viewing Freedom</title><link>https://en.1991421.cn/2025/06/07/how-to-build-a-nas-media-library/</link><pubDate>Sat, 07 Jun 2025 22:46:20 +0800</pubDate><guid>https://en.1991421.cn/2025/06/07/how-to-build-a-nas-media-library/</guid><description>&lt;blockquote>
&lt;p>Recently saw many people discussing NAS media library setup. As a long-term Synology NAS user, I&amp;rsquo;ll also share my approach.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-07-225948.JPG"
alt="https://static.1991421.cn/2025/2025-06-07-225948.JPG"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="hardware-equipment">
&lt;a class="heading-anchor-link" href="#hardware-equipment">Hardware Equipment&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="hardware-equipment"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>First about hardware, I&amp;rsquo;m still using the budget &lt;code>Synology NAS DS218j&lt;/code> bought in 2019. Configuration isn&amp;rsquo;t high, but sufficient.&lt;/p>
&lt;p>&lt;strong>Note: Regarding NAS purchase configuration selection, personally think sufficient is enough, but pay attention to having more drive bays to avoid inability to expand hard drive space later.&lt;/strong>&lt;/p>
&lt;h2 id="setup-steps">
&lt;a class="heading-anchor-link" href="#setup-steps">Setup Steps&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="setup-steps"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Set up &lt;code>alist&lt;/code> service, find a cloud provider&amp;rsquo;s server to build it, supporting external access.&lt;/p>
&lt;ul>
&lt;li>I currently use &lt;code>Oracle Cloud's permanently free server&lt;/code>, low configuration but sufficient.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>alist service mounts &lt;code>Quark Cloud Drive resources&lt;/code>, can also be other cloud drive resources.&lt;/p>
&lt;ul>
&lt;li>If you purchased &lt;code>88vip&lt;/code>, you can exchange for Quark Cloud Drive membership benefits, giving you &lt;code>6T&lt;/code> space.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>alist service &lt;code>enables WebDAV service&lt;/code>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>NAS sync cloud service adds alist&amp;rsquo;s WebDAV service, so resources sync to NAS locally.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-07-234735.jpeg"
alt="https://static.1991421.cn/2025/2025-06-07-234735.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>NAS then enables WebDAV service, mounting resources synced in step 4. If you have public IP at home, directly configure DDNS, so you can access from anywhere.&lt;/p>
&lt;ul>
&lt;li>For example, Unicom provides free public IP, just apply, no need to buy fixed IP here (100CNY/month, having it is definitely better).
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-07-232328.jpeg"
alt="https://static.1991421.cn/2025/2025-06-07-232328.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>For Apple ecosystem users, you can use &lt;code>infuse&lt;/code> app to add such WebDAV resources. Non-Apple users find corresponding methods supporting WebDAV mounting.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-07-232720.jpeg"
alt="https://static.1991421.cn/2025/2025-06-07-232720.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Note: If it&amp;rsquo;s Baidu Cloud Drive resources, since NAS Sync service directly supports adding, you can also skip alist.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="media-viewing-software">
&lt;a class="heading-anchor-link" href="#media-viewing-software">Media Viewing Software&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="media-viewing-software"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Apple users, recommend using &lt;code>Infuse&lt;/code>. Infuse supports cross-platform Mac/Apple TV/iPad/iPhone devices, and supports iCloud sync configuration items, making unified management and viewing convenient.&lt;/li>
&lt;li>Android users, can consider trying &lt;code>VidHub&lt;/code>.&lt;/li>
&lt;li>Besides the above app form access, consider directly accessing NAS via web to watch, or disk mount sharing.&lt;/li>
&lt;/ol>
&lt;h2 id="chrome-synology-download-plugin">
&lt;a class="heading-anchor-link" href="#chrome-synology-download-plugin">Chrome Synology Download Plugin&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="chrome-synology-download-plugin"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here recommend Synology&amp;rsquo;s official &lt;a href="https://chromewebstore.google.com/detail/nas-download-manager-for/iaijiochiiocodhamehbpmdlobhgghgi" target="_blank" rel="noopener">download plugin&lt;/a>. This way, besides cloud drive saving resources, you can also usually see some movie resources, directly right-click choose Synology download. After completion, can watch with Infuse etc.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-07-230738.jpeg"
alt="https://static.1991421.cn/2025/2025-06-07-230738.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-07-231156.jpeg"
alt="https://static.1991421.cn/2025/2025-06-07-231156.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>NAS is essentially a private cloud. Paired with public IP, capabilities become freer, media viewing is a very common scenario. Personally think domestic media sites all have somewhat poor experience, like member-exclusive ads, so building a personal media library as supplement is a good choice.&lt;/li>
&lt;li>Based on the above media service setup, I can actually add resources directly to cloud drive anywhere, home NAS will automatically sync resources, or directly use Synology official plugin to add any torrent resources, NAS directly downloads. Finally go home or anywhere directly use infuse etc. apps to watch.&lt;/li>
&lt;/ol></description></item><item><title>Do MacBooks Need Screen Protectors?</title><link>https://en.1991421.cn/2025/06/04/macbook-protector-worth-it-yes/</link><pubDate>Wed, 04 Jun 2025 09:22:39 +0800</pubDate><guid>https://en.1991421.cn/2025/06/04/macbook-protector-worth-it-yes/</guid><description>&lt;blockquote>
&lt;p>After owning multiple MacBooks, I’ve gone from bare screens to stick-on films and back again. Community threads reminded me how divisive this topic is, so here’s a structured look at the trade-offs and maintenance tips.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-04-093033.jpeg"
alt="MacBook display"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="going-bare-no-film">
&lt;a class="heading-anchor-link" href="#going-bare-no-film">Going Bare (No Film)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="going-bare-no-film"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>MacBook Pro’s Liquid Retina XDR display looks best without any overlay—maximum brightness, contrast, and color accuracy.&lt;/li>
&lt;/ul>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Everyday cleaning tempts you to reach for any tissue or wipe; abrasive fibers can introduce micro-scratches.&lt;/li>
&lt;li>Friends instinctively tap the screen while pointing things out.&lt;/li>
&lt;li>Closing the lid with a cable or adapter left on the keyboard risks gouging the panel.&lt;/li>
&lt;/ul>
&lt;h3 id="cleaning-tips">
&lt;a class="heading-anchor-link" href="#cleaning-tips">Cleaning Tips&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cleaning-tips"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Use a microfiber cloth (Apple’s polishing cloth or a reputable third-party option).&lt;/li>
&lt;li>If needed, apply display-safe cleaner to the cloth—not directly on the screen—and wipe gently.&lt;/li>
&lt;li>Avoid corrosive liquids and excessive pressure.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-05-210258.jpeg"
alt="Cleaning cloth"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;blockquote>
&lt;p>Fun fact: starting with the 2015 12&amp;quot; MacBook, Apple stopped bundling a cloth. Later MacBook Pro (2016) and MacBook Air (2018) models followed suit.&lt;/p>
&lt;/blockquote>
&lt;p>Apple’s full cleaning guidance: &lt;a href="https://support.apple.com/zh-cn/103258" target="_blank" rel="noopener">https://support.apple.com/zh-cn/103258&lt;/a> (Chinese version)&lt;/p>
&lt;h2 id="using-a-screen-protector">
&lt;a class="heading-anchor-link" href="#using-a-screen-protector">Using a Screen Protector&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="using-a-screen-protector"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="pros-1">
&lt;a class="heading-anchor-link" href="#pros-1">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Guards against accidental touches, cables, or debris that might otherwise scar the coating.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-05-210436.jpeg"
alt="Protector example"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="cons-1">
&lt;a class="heading-anchor-link" href="#cons-1">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Adds reflections and dulls the display.&lt;/li>
&lt;li>Thick protectors (especially combined with keyboard covers) can press against the screen, leaving key outlines.&lt;/li>
&lt;li>Removing adhesive films can damage the original coating.&lt;/li>
&lt;/ul>
&lt;h3 id="cleaning-with-a-protector">
&lt;a class="heading-anchor-link" href="#cleaning-with-a-protector">Cleaning With a Protector&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cleaning-with-a-protector"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Same as above—just don’t press hard enough to crease the film.&lt;/p>
&lt;h2 id="soshould-you-use-one">
&lt;a class="heading-anchor-link" href="#soshould-you-use-one">So…Should You Use One?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="soshould-you-use-one"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>If you’re meticulous and enjoy the pristine look, skip the film and keep a cleaning kit handy.&lt;/li>
&lt;li>If you’d rather sacrifice a bit of clarity to avoid scratches—or you expect to peel it off later—use a protector.&lt;/li>
&lt;li>If you primarily run the MacBook in clamshell mode with an external display, a protector is unnecessary.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Best compromise: a magnetic protector.&lt;/strong> It attaches when needed and comes off without adhesive.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-06-05-205040.jpeg"
alt="Magnetic protector"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="accessories-to-avoid-">
&lt;a class="heading-anchor-link" href="#accessories-to-avoid-">Accessories to Avoid ❎&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accessories-to-avoid-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Hard shell cases—they trap heat and hurt thermals.&lt;/li>
&lt;li>Palm-rest or keyboard skins. Apple explicitly warns against closing the lid with them in place.
&lt;blockquote>
&lt;p>“If you use a camera cover, palm rest cover, or keyboard cover, remove it before closing your Mac notebook to avoid damaging the display.” — &lt;a href="https://support.apple.com/zh-cn/102051" target="_blank" rel="noopener">https://support.apple.com/zh-cn/102051&lt;/a> (Chinese)&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;/ol>
&lt;h2 id="my-current-setup">
&lt;a class="heading-anchor-link" href="#my-current-setup">My Current Setup&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-current-setup"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>I’ve been using stick-on glass protectors (e.g., a 58 CNY temper glass model from JD.com) but plan to switch to magnetic ones sold by Apple and third-party vendors.&lt;/li>
&lt;li>No other protective accessories.&lt;/li>
&lt;/ul>
&lt;h2 id="closing-thoughts">
&lt;a class="heading-anchor-link" href="#closing-thoughts">Closing Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="closing-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If I buy another Mac, I’ll go magnetic to balance aesthetics and protection. Got a better idea? Drop it in the comments.&lt;/p></description></item><item><title>Getting the iPhone 16 Pro: Great, But Also Has Issues</title><link>https://en.1991421.cn/2025/05/29/buy-iphone-16-pro/</link><pubDate>Thu, 29 May 2025 15:28:10 +0800</pubDate><guid>https://en.1991421.cn/2025/05/29/buy-iphone-16-pro/</guid><description>&lt;blockquote>
&lt;p>Now the 618 shopping festival lasts for months. Before June 18th even arrives, the activities have already started early. I couldn&amp;rsquo;t resist and got the iPhone 16 Pro in mid-month.
So far, I&amp;rsquo;ve been using it for several weeks. Here I&amp;rsquo;ll mark down my usage experience and also explain what I consider to be the issues with the 16.&lt;/p>
&lt;/blockquote>
&lt;h2 id="purchase-motivation">
&lt;a class="heading-anchor-link" href="#purchase-motivation">Purchase Motivation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchase-motivation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>My iPhone 12&amp;rsquo;s battery health is at &lt;code>79%&lt;/code>. Now whenever the battery drops to 10-20%, I can clearly feel it draining particularly fast. Additionally, this year some iPhone models have government subsidies (&lt;code>government subsidies for phones under 6000 yuan&lt;/code>). Considering that new phones released in October can&amp;rsquo;t possibly be cheaper than the 16 even at their lowest price, I decided to get the 16.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-29-185220.jpeg"
alt="https://static.1991421.cn/2025/2025-05-29-185220.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="128-or-256-non-pro-pro-or-pro-max">
&lt;a class="heading-anchor-link" href="#128-or-256-non-pro-pro-or-pro-max">128 or 256, Non-Pro, Pro or Pro Max&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="128-or-256-non-pro-pro-or-pro-max"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Initially, I was also torn about the configuration, but based on several points of analysis and elimination, I finally reached a conclusion. If you&amp;rsquo;re also struggling with which one to choose, you can refer to this.&lt;/p>
&lt;ol>
&lt;li>Storage Issue
&lt;ul>
&lt;li>With a limited budget, naturally bigger is better. I checked my previous &lt;code>iPhone 12 128G&lt;/code> and found I was using &lt;code>under 100G&lt;/code> of storage, so 128GB is sufficient for my current usage needs.&lt;/li>
&lt;li>If using Pro camera for video recording, it takes up more space, but I mainly take photos with little recording needs, so photography won&amp;rsquo;t cause storage shortage.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Pro or Non-Pro
&lt;ul>
&lt;li>Pro has better camera and screen, and I like photography.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Weight
&lt;ul>
&lt;li>Max weighs &lt;code>227g&lt;/code> which is heavier, while Pro is &lt;code>199g&lt;/code>. Everyone prefers lighter devices. Of course, Max&amp;rsquo;s biggest issue is the more beautiful price - even at 618&amp;rsquo;s lowest it would definitely be &lt;code>7K+&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Configuration
&lt;ul>
&lt;li>Pro&amp;rsquo;s configuration is higher than non-Pro, mainly the titanium body and camera lenses. I lean towards wanting a phone with a better camera.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>Based on using the government subsidy as much as possible within 6K, while balancing the several concerns mentioned above, I chose the base model &lt;code>iPhone 16 Pro 128G Natural Titanium&lt;/code>, purchased from JD at a price of &lt;code>5469 CNY&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Note: For 3C digital products without particularly large price differences, I personally still consider JD rather than PDD and other channels.&lt;/strong>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-29-183646.jpeg"
alt="https://static.1991421.cn/2025/2025-05-29-183646.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="accessories">
&lt;a class="heading-anchor-link" href="#accessories">Accessories&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As mentioned in my other article &lt;a href="https://1991421.cn/2025/05/28/should-you-use-iphone-case-lessons-learned/" target="_blank" rel="noopener">Do iPhones Need Cases and Screen Protectors? You&amp;rsquo;ll Understand After a Few Drops&lt;/a>, I currently only have the following accessories.&lt;/p>
&lt;ol>
&lt;li>SHANMO iPhone 16 Pro screen protector - HD anti-fingerprint borderless transparent window explosion-proof drop-proof non-full screen film, purchased from JD, &lt;code>18.4 CNY&lt;/code>&lt;/li>
&lt;li>Huaqiangbei iPhone MagSafe protective case, purchased from PDD, &lt;code>29.57 CNY&lt;/code>&lt;/li>
&lt;/ol>
&lt;h2 id="current-experience">
&lt;a class="heading-anchor-link" href="#current-experience">Current Experience&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-experience"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="advantages">
&lt;a class="heading-anchor-link" href="#advantages">Advantages&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="advantages"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The build quality is impeccable, the screen is first-class. I&amp;rsquo;ve always loved Apple&amp;rsquo;s display colors and color temperature.&lt;/li>
&lt;li>Dynamic Island is quite fun. I was using the 12 non-Pro before and hadn&amp;rsquo;t experienced it.&lt;/li>
&lt;li>Photo quality, especially at night, is excellent.&lt;/li>
&lt;/ol>
&lt;h3 id="disadvantages---issues">
&lt;a class="heading-anchor-link" href="#disadvantages---issues">Disadvantages - Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="disadvantages---issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Both the left-side mute button and volume buttons are buttons, causing me to frequently &lt;code>accidentally press&lt;/code> them when pressing blindly. I think this design is a failure and suspect the iPhone team&amp;rsquo;s testing wasn&amp;rsquo;t thorough enough.&lt;/li>
&lt;li>The newly added camera button on the right side, I admit, is convenient when taking photos, but without it there wouldn&amp;rsquo;t be much of a problem, so isn&amp;rsquo;t it quite &lt;code>redundant&lt;/code>? Simplicity no longer exists, making the physical buttons feel very bloated. The overall design aesthetics of the iPhone is at least far worse than the iPhone 4 era. The Cook era always feels like the aesthetics have deteriorated significantly, let alone surpassing previous designs.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-28-154140.jpeg"
alt="https://static.1991421.cn/2025/2025-05-28-154140.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;blockquote>
&lt;p>Speaking of disadvantages, besides these above, the entire Apple ecosystem has quite a few shortcomings, such as macOS now having many bugs, iPhone&amp;rsquo;s yearly toothpaste-squeezing updates, gradually declining aesthetics, the perpetually unchanged stupid Siri, the endlessly delayed PowerPoint-version AI, and so on.&lt;/p>
&lt;/blockquote>
&lt;h2 id="my-apple-ecosystem">
&lt;a class="heading-anchor-link" href="#my-apple-ecosystem">My Apple Ecosystem&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-apple-ecosystem"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Although iPhone has its shortcomings, currently Apple&amp;rsquo;s ecosystem closed-loop experience is still the best. For example, my current Apple ecosystem device list is as follows. I&amp;rsquo;m now in a state of complaining while still using these Apple products.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-29-184213.PNG"
alt="https://static.1991421.cn/2025/2025-05-29-184213.PNG"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Overall, the iPhone 16 Pro is the first time I&amp;rsquo;ve clearly felt design flaws, as mentioned above with the mute button and camera button, but it&amp;rsquo;s still a well-balanced excellent phone. Over these years, the charm and aura of iPhone and even Apple has been genuinely fading bit by bit, and many friends around me have already switched to Android.
I hope Apple can make some big moves this year, whether in software or hardware, otherwise I&amp;rsquo;ll also consider switching brands.&lt;/p></description></item><item><title>One Month In: Monetizing a WeChat Official Account</title><link>https://en.1991421.cn/2025/05/26/make-money-with-wechat-mp/</link><pubDate>Mon, 26 May 2025 22:20:27 +0800</pubDate><guid>https://en.1991421.cn/2025/05/26/make-money-with-wechat-mp/</guid><description>&lt;blockquote>
&lt;p>While chatting in a creator group, I realized I could try a WeChat Official Account. I’ve been blogging for 10 years—why not publish on another platform? It could earn some money and reach more readers. Exciting thought.&lt;/p>
&lt;p>So I went for it. After a little over a month, I got the account up and running and even made a bit. Here’s a summary of what I did.&lt;/p>
&lt;/blockquote>
&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I had a WeChat Official Account before, but with a narrow focus (Alfred), and Alfred has faded over the years. That account wasn’t updated much and had few followers—about &lt;code>137 (as of 3/26)&lt;/code>. After deciding to reboot, I renamed the account and adjusted the positioning.&lt;/p>
&lt;h2 id="metrics">
&lt;a class="heading-anchor-link" href="#metrics">Metrics&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="metrics"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After a month of publishing, follower and engagement numbers look decent:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-26-222705.jpeg"
alt="https://static.1991421.cn/2025/2025-05-26-222705.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Some short “interest” posts performed surprisingly well in reads—pleasant surprise.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-26-224447.jpeg"
alt="https://static.1991421.cn/2025/2025-05-26-224447.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-26-224542.jpeg"
alt="https://static.1991421.cn/2025/2025-05-26-224542.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-27-085528.jpeg"
alt="https://static.1991421.cn/2025/2025-05-27-085528.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Many posts exceeded 10k reads; several hit 30–40k.&lt;/p>
&lt;h2 id="earnings">
&lt;a class="heading-anchor-link" href="#earnings">Earnings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="earnings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If I’m doing this, I’m thinking about revenue—money motivates, and I also enjoy writing. Win-win.&lt;/p>
&lt;p>&lt;code>I enabled ads on May 15, so revenue started on 5/16.&lt;/code>
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-26-222828.jpeg"
alt="https://static.1991421.cn/2025/2025-05-26-222828.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="current-thoughts">
&lt;a class="heading-anchor-link" href="#current-thoughts">Current Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Growth looks good. If all goes well, I should hit &lt;code>1,000 followers&lt;/code> in June—a new level.&lt;/li>
&lt;li>Content quality needs to go up. With ~20k reads, eCPM is only 2–3 CNY. If I can push it to 30+, revenue won’t be just a few dozen yuan—it could be much higher.&lt;/li>
&lt;li>Mix in some “day-to-day diary” posts. From the data, high-quality/most-liked/high-revenue posts often aren’t the same thing; balance matters.&lt;/li>
&lt;li>The “Wen Yi Wen” Q&amp;amp;A feature (launched in 2023) seems worth trying. It integrates with Official Accounts and can drive traffic. I used to like Zhihu; since it’s fading, I can switch to “Wen Yi Wen” with little extra cost.&lt;/li>
&lt;/ol>
&lt;h2 id="plan">
&lt;a class="heading-anchor-link" href="#plan">Plan&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="plan"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Keep publishing through June. Target: 50 CNY/day, 1k/month. That’s motivating. I’ll keep blogging regardless; monetization just nudges strategy and focus.&lt;/p>
&lt;h2 id="course-in-the-works-">
&lt;a class="heading-anchor-link" href="#course-in-the-works-">Course in the Works 📣&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="course-in-the-works-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I’m documenting lessons learned and turning them into a course. Tech folks have advantages in the creator space—tools, and a focus on what matters: data, audience, content quality.
I’ll package these into a course. It helps others and generates income—win-win.&lt;/p>
&lt;p>Interested? Give it a try 👇
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-26-223853.jpeg"
alt="https://static.1991421.cn/2025/2025-05-26-223853.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Keep pushing the Official Account.&lt;/li>
&lt;li>Keep enriching the course—help others and earn at the same time.&lt;/li>
&lt;/ol></description></item><item><title>How to Get the Best Price for WeRead Membership: Cheapest Purchase Channels and Money-Saving Tips</title><link>https://en.1991421.cn/2025/05/18/weread-member/</link><pubDate>Sun, 18 May 2025 21:53:20 +0800</pubDate><guid>https://en.1991421.cn/2025/05/18/weread-member/</guid><description>&lt;blockquote>
&lt;p>I’ve been a WeRead member for years. Buying membership directly in the app can be pricey. Here are cheaper options.&lt;/p>
&lt;/blockquote>
&lt;h2 id="weread-app--official-promo-price">
&lt;a class="heading-anchor-link" href="#weread-app--official-promo-price">WeRead App — Official Promo Price&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="weread-app--official-promo-price"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The most common path: log into the WeRead app. During holidays (e.g., Spring Festival), there are promo prices around 168/188 CNY. You’ll need to wait for the event.&lt;/p>
&lt;h2 id="xianyu-idle-fish">
&lt;a class="heading-anchor-link" href="#xianyu-idle-fish">Xianyu (Idle Fish)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xianyu-idle-fish"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Search “WeRead” on Xianyu; you’ll find annual memberships. Prices fluctuate—recently 167 CNY, sometimes 138 CNY. You can also check PDD/Taobao; prices are similar.&lt;/p>
&lt;p>Note: Xianyu can be messy. Only use options that directly recharge your own phone number. Safety first.&lt;/p>
&lt;h2 id="weread-mini-shop">
&lt;a class="heading-anchor-link" href="#weread-mini-shop">WeRead Mini Shop&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="weread-mini-shop"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Search “WeRead Mini Shop” in WeChat. Annual membership is currently 168 CNY consistently—no need to wait for promos.&lt;/p>
&lt;p>Note: It’s an official shop, so no worries.&lt;/p>
&lt;img src="https://static.1991421.cn/2025/2025-05-18-215931.jpeg" alt="WeRead membership pricing comparison screenshot 1" style="zoom:50%;" />
&lt;img src="https://static.1991421.cn/2025/2025-05-18-215829.jpeg" alt="WeRead membership pricing comparison screenshot 2" style="zoom:50%;" />
&lt;h2 id="weread--redeem-with-trial-cards">
&lt;a class="heading-anchor-link" href="#weread--redeem-with-trial-cards">WeRead — Redeem with Trial Cards&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="weread--redeem-with-trial-cards"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Trial cards can be redeemed for cheaper membership—so remember to claim them daily.&lt;/p>
&lt;p>Note: Trial card benefits differ from full membership.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-18-220208.jpeg"
alt="WeRead trial card redemption screen"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="weread-app--365-day-reading-challenge">
&lt;a class="heading-anchor-link" href="#weread-app--365-day-reading-challenge">WeRead App — 365-Day Reading Challenge&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="weread-app--365-day-reading-challenge"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Pay 50 CNY to join. If you read for 360 days, you can redeem a full-year membership—effectively 50 CNY/year.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-18-220653.jpeg"
alt="WeRead 365-day reading challenge screen"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Claim the weekly reading rewards.&lt;/li>
&lt;li>Prefer trial cards over book coins. Book coins expire; trial cards don’t.&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>These are the cheapest options I know. Personally, I’ve used Xianyu direct-recharge before. Recently I joined the 365-day challenge, and I stack trial cards from daily rewards for occasional redemptions. Ideally, that means ~50 CNY/year. It’s hard to stick with—but worth trying.&lt;/p></description></item><item><title>Real Experience: My Current Favorite Power Bank</title><link>https://en.1991421.cn/2025/05/17/the-best-battery-pack/</link><pubDate>Sat, 17 May 2025 18:24:22 +0800</pubDate><guid>https://en.1991421.cn/2025/05/17/the-best-battery-pack/</guid><description>&lt;blockquote>
&lt;p>There don&amp;rsquo;t seem to be that many trustworthy power bank brands to pick from. The really niche ones can be cheap, but safety is a concern — remember how xxx had units catching fire before.&lt;/p>
&lt;p>I&amp;rsquo;ve bought quite a few power banks over time. With some spare time lately, I figured I&amp;rsquo;d do a quick roundup of the ones I own.&lt;/p>
&lt;/blockquote>
&lt;h2 id="what-i-bought">
&lt;a class="heading-anchor-link" href="#what-i-bought">What I Bought&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-i-bought"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Over the past two years I picked up the following power banks; none of them were expensive.&lt;/p>
&lt;ol>
&lt;li>BULL 10,000 mAh wireless power bank
&lt;ul>
&lt;li>Bought on PDD, &lt;code>130CNY&lt;/code>&lt;/li>
&lt;li>I thought of BULL because their power strips left a strong impression. I wanted to see how their power banks compare.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Anker MagSafe magnetic wireless power bank (10,000 mAh)
&lt;ul>
&lt;li>Bought on JD, &lt;code>113CNY&lt;/code>; I ended up buying two over time&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Xiaomi power bank with built-in cable (20,000 mAh)
&lt;ul>
&lt;li>33W, Deep Space Blue&lt;/li>
&lt;li>Bought on JD, &lt;code>123CNY&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>I had bought other models before, but they&amp;rsquo;re too old to be worth discussing here.&lt;/p>
&lt;h2 id="comparison-photos">
&lt;a class="heading-anchor-link" href="#comparison-photos">Comparison Photos&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="comparison-photos"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here&amp;rsquo;s a quick look at the design differences.&lt;/p>
&lt;h3 id="anker-vs-xiaomi">
&lt;a class="heading-anchor-link" href="#anker-vs-xiaomi">Anker vs Xiaomi&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="anker-vs-xiaomi"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Anker on the left (206.5 g), Xiaomi on the right. Since the Xiaomi is 20,000 mAh, it&amp;rsquo;s larger and heavier (349 g). In actual use, it feels substantial in the hand.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-18-212611.jpeg"
alt="https://static.1991421.cn/2025/2025-05-18-212611.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="bull-vs-anker">
&lt;a class="heading-anchor-link" href="#bull-vs-anker">BULL vs Anker&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bull-vs-anker"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>BULL on the left, Anker on the right.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-18-212631.jpeg"
alt="https://static.1991421.cn/2025/2025-05-18-212631.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Before buying I thought BULL and Anker would be similar, but in hand they&amp;rsquo;re noticeably different. The BULL is thicker with a slightly smaller footprint, while the Anker is thinner with a slightly larger footprint.&lt;/p>
&lt;p>With extended use, I find thinness matters more. When the MagSafe pack is attached, you&amp;rsquo;re holding the phone one‑handed; the thinner pack simply feels more comfortable. Also, in my experience, Anker&amp;rsquo;s charging detection is a bit more responsive.&lt;/p>
&lt;p>That said, the BULL power bank&amp;rsquo;s build quality is solid—no worse than Anker. I just hope BULL makes a thinner version in the future.&lt;/p>
&lt;h2 id="wireless-or-wired">
&lt;a class="heading-anchor-link" href="#wireless-or-wired">Wireless or Wired&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wireless-or-wired"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After getting used to wireless, I rarely want to use a cable. Snapping the pack onto the phone is just too comfortable. Only in extreme cases—when I need to charge urgently and use the phone immediately—do I go wired.&lt;/p>
&lt;h2 id="current-usage">
&lt;a class="heading-anchor-link" href="#current-usage">Current Usage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-usage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>These days I mainly use the Anker 10,000 and the Xiaomi 20,000. I use the Anker for wireless only, and the Xiaomi for wired—since it has a built‑in USB‑C cable, there&amp;rsquo;s no need to bring a separate one. For long days out I carry the Xiaomi; for short outings the Anker is enough.&lt;/p>
&lt;p>The BULL is thicker, so it loses out to the Anker—no strong reason for me to pick BULL.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you haven&amp;rsquo;t tried a wireless battery pack, give it a shot. Most phones support wireless charging now, and it&amp;rsquo;s very convenient in daily use.&lt;/p></description></item><item><title>Apple Removes the AirTag Battery Indicator from the Find My App</title><link>https://en.1991421.cn/2025/05/17/apple-removes-airtag-battery-level-icon-find-my/</link><pubDate>Sat, 17 May 2025 12:26:08 +0800</pubDate><guid>https://en.1991421.cn/2025/05/17/apple-removes-airtag-battery-level-icon-find-my/</guid><description>&lt;blockquote>
&lt;p>I only noticed this because one of my AirTags suddenly died and I realized the Find My app no longer shows a battery indicator for AirTags, while it still does for devices like the iPhone and iPad. After some digging I learned that Apple removed it starting with iOS 15.6.&lt;/p>
&lt;/blockquote>
&lt;h2 id="no-battery-indicator-for-airtag">
&lt;a class="heading-anchor-link" href="#no-battery-indicator-for-airtag">No Battery Indicator for AirTag&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="no-battery-indicator-for-airtag"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-17-123204.jpeg"
alt="https://static.1991421.cn/2025/2025-05-17-123204.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="other-devices-still-show-the-battery-level">
&lt;a class="heading-anchor-link" href="#other-devices-still-show-the-battery-level">Other Devices Still Show the Battery Level&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other-devices-still-show-the-battery-level"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-17-123356.jpeg"
alt="https://static.1991421.cn/2025/2025-05-17-123356.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="versions-after-ios-156-removed-it">
&lt;a class="heading-anchor-link" href="#versions-after-ios-156-removed-it">Versions After iOS 15.6 Removed It&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="versions-after-ios-156-removed-it"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Below is a translated summary of the earlier &lt;a href="https://www.macrumors.com/2022/07/21/apple-removes-airtag-battery-level-icon-find-my/" target="_blank" rel="noopener">report&lt;/a>.&lt;/p>
&lt;p>Apple removed the AirTag battery indicator from the Find My app in iOS 15.6, which caught many users off guard.&lt;/p>
&lt;p>In earlier versions of iOS, when you opened the details page for an AirTag, a battery icon appeared under the device name and location. It didn&amp;rsquo;t show an exact percentage, but it gave you a rough idea of whether the battery was running low.
&lt;figure class="image-figure">
&lt;img
src="https://images.macrumors.com/t/AROO3dKzkVPtyvJk-rWP-owLi3M=/800x0/article-new/2022/07/airtag-battery-icon.jpg?lossy"
alt="https://images.macrumors.com/t/AROO3dKzkVPtyvJk-rWP-owLi3M=/800x0/article-new/2022/07/airtag-battery-icon.jpg?lossy"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>From iOS 15.6 onward, the icon disappeared. Apple never mentioned the change in the release notes, but it was quietly taken out of the system.&lt;/p>
&lt;p>Now, the Find My app &lt;strong>only alerts you when an AirTag battery is critically low&lt;/strong>, prompting you to replace it. You no longer see the routine battery icon status.&lt;/p>
&lt;p>Apple also removed the instructions for checking battery levels from its &lt;a href="https://support.apple.com/en-us/HT211670" target="_blank" rel="noopener">AirTag support document&lt;/a>. The page now simply explains that AirTags use a replaceable battery and will notify you when it&amp;rsquo;s running low.&lt;/p>
&lt;p>The AirTag relies on a standard CR2032 coin cell battery, which Apple says should last about a year. Replacing it is straightforward: press down on the metal back of the AirTag and twist to open it.&lt;/p>
&lt;p>Some speculate that Apple removed the icon to &lt;strong>simplify the UI&lt;/strong>, while others believe the battery indicator might not have been accurate enough and could have misled users.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>In practice, the Find My app now alerts you only when the battery is low.&lt;/li>
&lt;li>This change hasn&amp;rsquo;t affected me much, since the AirTag still has excellent battery life.&lt;/li>
&lt;/ol></description></item><item><title>Hands-On Review: My Current Favorite Mouse</title><link>https://en.1991421.cn/2025/05/15/the-best-mouse/</link><pubDate>Thu, 15 May 2025 18:53:50 +0800</pubDate><guid>https://en.1991421.cn/2025/05/15/the-best-mouse/</guid><description>&lt;blockquote>
&lt;p>The backpack I shared earlier struck a chord with many people, so I&amp;rsquo;m keeping the sharing streak going. Today I&amp;rsquo;m talking about my mouse.&lt;/p>
&lt;/blockquote>
&lt;h2 id="logitech-m720---my-daily-driver">
&lt;a class="heading-anchor-link" href="#logitech-m720---my-daily-driver">Logitech M720 - My Daily Driver&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="logitech-m720---my-daily-driver"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I bought it on JD.com in 2023 for &lt;code>170CNY&lt;/code>. I ended up buying two. Both are still alive: one lives at the office, and the other stays at home, where it regularly switches across multiple devices.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-15-231817.jpg"
alt="https://static.1991421.cn/2025/2025-05-15-231817.jpg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="how-i-use-it">
&lt;a class="heading-anchor-link" href="#how-i-use-it">How I Use It&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-i-use-it"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Here&amp;rsquo;s how I use it. I used to haul my &lt;code>laptop + mouse&lt;/code> home so I could keep grinding after hours. I brought the mouse along for familiarity; otherwise I&amp;rsquo;d have to pair whatever mouse was lying around at home, and if it was a different shape it always felt awkward. Once I had a multi-device mouse, I could just bring the laptop home, press the device switch on the home mouse to jump to the work computer, and keep working seamlessly. If I needed to hop back to the home Mac mini or MBA, one more click and I&amp;rsquo;m back. It&amp;rsquo;s so much more comfortable overall.&lt;/p>
&lt;p>That&amp;rsquo;s a typical scenario. So what are the pros and cons of this mouse in my setup?&lt;/p>
&lt;h2 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Multi-device pairing with support for three devices
&lt;ul>
&lt;li>That covers me perfectly: company MBP, home MBA, and Mac mini&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Battery life
&lt;ul>
&lt;li>Logitech&amp;rsquo;s battery life is solid. Plus I no longer commute with the mouse, so I don&amp;rsquo;t forget to power it off. Parked at home, it&amp;rsquo;s very power-efficient—no issues.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Dual mode with wireless USB dongle support
&lt;ul>
&lt;li>If Bluetooth fails, the wireless receiver is a fallback. I rarely need it, but it&amp;rsquo;s nice to have.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Size and shape
&lt;ul>
&lt;li>This mouse isn&amp;rsquo;t small, and once you get used to it the grip feels great. Tiny mice make my hand cramp because I can&amp;rsquo;t stretch out. Your mileage may vary.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-15-230045.jpeg"
alt="https://static.1991421.cn/2025/2025-05-15-230045.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I honestly don&amp;rsquo;t have any complaints. It&amp;rsquo;s more than good enough. If a future revision adds USB-C charging, that would be icing on the cake.&lt;/p>
&lt;h2 id="why-i-didnt-buy-a-logitech-mx-mouse">
&lt;a class="heading-anchor-link" href="#why-i-didnt-buy-a-logitech-mx-mouse">Why I Didn&amp;rsquo;t Buy a Logitech MX Mouse&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-i-didnt-buy-a-logitech-mx-mouse"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Because it&amp;rsquo;s expensive. I wanted multi-device switching and dual-mode connectivity, and after filtering the options the M720 was the most affordable that checked those boxes. The MX lineup has plenty of other perks, but given the price I can live without them.&lt;/p>
&lt;h2 id="other-mice-ive-used">
&lt;a class="heading-anchor-link" href="#other-mice-ive-used">Other Mice I&amp;rsquo;ve Used&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other-mice-ive-used"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Before the M720 I tried quite a few other mice. Here are the main ones.&lt;/p>
&lt;h3 id="logitech-m337-m336">
&lt;a class="heading-anchor-link" href="#logitech-m337-m336">Logitech M337 (M336)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="logitech-m337-m336"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Bluetooth mouse around the 100 CNY mark. I owned two. One died, and the other didn&amp;rsquo;t support multi-device pairing, so it didn&amp;rsquo;t meet my needs.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-15-230543.jpeg"
alt="https://static.1991421.cn/2025/2025-05-15-230543.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="logitech-m275-mouse">
&lt;a class="heading-anchor-link" href="#logitech-m275-mouse">Logitech M275 Mouse&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="logitech-m275-mouse"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Wireless mouse, roughly 100 CNY. After using it, I wasn&amp;rsquo;t a fan.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-15-230702.jpeg"
alt="https://static.1991421.cn/2025/2025-05-15-230702.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="logitech-m185-mouse">
&lt;a class="heading-anchor-link" href="#logitech-m185-mouse">Logitech M185 Mouse&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="logitech-m185-mouse"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Wireless mouse priced around 50 CNY.&lt;/p>
&lt;p>It&amp;rsquo;s billed as the king of bang-for-buck, and it genuinely deserves that title. Compact, available in red and black, and built well. Just make sure you&amp;rsquo;re not buying the silent-click version if you don&amp;rsquo;t need it.
If you like smaller mice and don&amp;rsquo;t care about Bluetooth, this one is absolutely worth picking up.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-15-224004.jpeg"
alt="https://static.1991421.cn/2025/2025-05-15-224004.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="microsoft-wireless-mobile-mouse-4000">
&lt;a class="heading-anchor-link" href="#microsoft-wireless-mobile-mouse-4000">Microsoft Wireless Mobile Mouse 4000&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="microsoft-wireless-mobile-mouse-4000"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Wireless mouse priced above 100 CNY.&lt;/p>
&lt;p>I wanted to try a Microsoft mouse without spending too much, so I went with this one. It looks nice, but the build quality wasn&amp;rsquo;t great and it eventually died on me.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-15-231121.jpeg"
alt="https://static.1991421.cn/2025/2025-05-15-231121.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="perixx-pm804-ergonomic-vertical-mouse">
&lt;a class="heading-anchor-link" href="#perixx-pm804-ergonomic-vertical-mouse">Perixx PM804 Ergonomic Vertical Mouse&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="perixx-pm804-ergonomic-vertical-mouse"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Bluetooth mouse, about 140 CNY.&lt;/p>
&lt;p>I bought it out of curiosity. After a stretch of trying to get used to a vertical mouse, I gave up.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-15-233653.jpeg"
alt="https://static.1991421.cn/2025/2025-05-15-233653.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="tips-for-buying-and-using-mice">
&lt;a class="heading-anchor-link" href="#tips-for-buying-and-using-mice">Tips for Buying and Using Mice&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tips-for-buying-and-using-mice"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After going through so many mice, here are a few takeaways.&lt;/p>
&lt;ul>
&lt;li>Prioritize Bluetooth. It&amp;rsquo;s far more convenient than a wireless dongle, and once you get used to it there&amp;rsquo;s no going back. Multi-mode support is even better.&lt;/li>
&lt;li>If your mouse uses replaceable batteries, I strongly recommend skipping rechargeable batteries. Swapping in fresh ones is faster and means you never have to worry about charging.&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>A mouse is a high-frequency tool, so it&amp;rsquo;s worth getting one that feels right, whether it&amp;rsquo;s cheap or pricey. That said, within a set budget there&amp;rsquo;s often not much to nitpick.&lt;/p>
&lt;p>Those are all the mice I&amp;rsquo;ve used. Feel free to share the ones you love.&lt;/p></description></item><item><title>Real Experience: My Current Favorite Backpack</title><link>https://en.1991421.cn/2025/05/10/the-best-backpack/</link><pubDate>Sat, 10 May 2025 11:30:14 +0800</pubDate><guid>https://en.1991421.cn/2025/05/10/the-best-backpack/</guid><description>&lt;blockquote>
&lt;p>Recently, during a conversation with colleagues about backpack choices for us working folks, I couldn&amp;rsquo;t help but talk enthusiastically about the backpack I&amp;rsquo;ve been using for about 5 years. Additionally, during two trips around the May Day holiday, I tried using two other backpacks, which made me appreciate my current old bag even more.&lt;/p>
&lt;p>Regarding backpacks, you might have similar needs and frustrations as I do, so let me share my thoughts here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="nayo-almighty-backpack---currently-my-favorite">
&lt;a class="heading-anchor-link" href="#nayo-almighty-backpack---currently-my-favorite">Nayo Almighty Backpack - Currently My Favorite&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="nayo-almighty-backpack---currently-my-favorite"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I got this in August 2020, choosing the large size &lt;code>32L&lt;/code>. I purchased it from the official website using a discount code for &lt;code>$48.99 USD&lt;/code>, which was equivalent to &lt;code>317.055 CNY&lt;/code> at the time.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-11-224454.jpeg"
alt="https://static.1991421.cn/2021/2021-01-11-224454.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>The screenshot above was taken when I visited Erhai Lake in 2020. Not bad, right? Even when the backpack is empty, it can stand upright on its own.&lt;/p>
&lt;p>&lt;strong>This model has now been upgraded to the 3rd generation, which should be even better than mine.&lt;/strong>&lt;/p>
&lt;h3 id="multi-functional-features">
&lt;a class="heading-anchor-link" href="#multi-functional-features">Multi-functional Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="multi-functional-features"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>What impressed me about this backpack is its multi-functionality. Many detailed design elements perfectly solve my specific scenarios and pain points.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-10-114935.jpeg"
alt="https://static.1991421.cn/2025/2025-05-10-114935.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-10-114028.jpg"
alt="https://static.1991421.cn/2025/2025-05-10-114028.jpg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Here are some specific scenarios:&lt;/p>
&lt;ol>
&lt;li>Sunglasses - Position #2 allows you to hang sunglasses directly.&lt;/li>
&lt;li>Keys - Position #3 has a zippered pocket specifically for keychains.&lt;/li>
&lt;li>ID card - Position #6&amp;rsquo;s zippered compartment is perfect for it, no need to take off the backpack.&lt;/li>
&lt;li>Luggage - Position #4 can be placed directly on the luggage handle, so you can pull both the suitcase and backpack together.&lt;/li>
&lt;/ol>
&lt;p>And so on. There are quite a few scenarios where it solves pain points like these. With other regular backpacks, I simply couldn&amp;rsquo;t achieve this level of convenience.&lt;/p>
&lt;p>Additionally, the interior compartments are well-divided, so when I travel and pack clothes/electronics, everything stays organized.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-10-115109.jpeg"
alt="https://static.1991421.cn/2025/2025-05-10-115109.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>In summary, this backpack currently meets my needs for commuting, travel, and various other scenarios. It&amp;rsquo;s truly a multi-purpose bag.&lt;/p>
&lt;p>Let me break down the overall pros and cons.&lt;/p>
&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Large capacity.&lt;/li>
&lt;li>Well-designed features, such as the strap pocket for keychains, insulated zippered compartment, sunglasses hanging spot, etc. The best part is that it can stand upright even when empty.&lt;/li>
&lt;li>Reasonable price. Compared to the hundred-yuan backpacks I bought before, it&amp;rsquo;s not expensive. I checked and the 2nd generation currently sold on JD is slightly more expensive than what I paid with the discount code, but not by much.&lt;/li>
&lt;/ul>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I personally think the build quality is just average. However, checking the official website, it has now been upgraded to the 3rd generation, while JD still sells the 2nd generation. Both are newer than mine, so this shortcoming might have been improved.&lt;/p>
&lt;h3 id="interesting-point">
&lt;a class="heading-anchor-link" href="#interesting-point">Interesting Point&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="interesting-point"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Sometimes when going through subway security, my backpack can pass through the scanner directly even when it&amp;rsquo;s empty, due to its naturally bulky and heavy structure. So is this a pro or a con? I&amp;rsquo;ll categorize it as &amp;ldquo;interesting.&amp;rdquo;&lt;/p>
&lt;h2 id="other-backpacks-i-currently-own">
&lt;a class="heading-anchor-link" href="#other-backpacks-i-currently-own">Other Backpacks I Currently Own&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other-backpacks-i-currently-own"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Recently, my company issued an Anta Baichuan backpack, priced at around 300 CNY. I used it during the May Day trip and found it comfortable for the waist, but the pain point is that when I want to store keys, there&amp;rsquo;s no dedicated place for them. With only a few interior compartments, I often put things in and then can&amp;rsquo;t remember which layer I used, which is very annoying.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-10-115858.jpeg"
alt="https://static.1991421.cn/2025/2025-05-10-115858.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ul>
&lt;li>I also have several other backpacks bought years ago or cheap ones issued by the company. They all have similar problems - they don&amp;rsquo;t solve many practical pain points and merely provide some crude pockets for storage.&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>I looked up Nayo Smart and it&amp;rsquo;s a domestic Chinese brand, definitely not a big-name brand. However, I think the design is quite thoughtful. If you&amp;rsquo;re not pursuing big brands, it&amp;rsquo;s worth trying.&lt;/li>
&lt;li>From my current perspective, I can abandon my plans to try other backpacks several more times. This backpack really is the most suitable for me. It seems like I can use it for a few more years before upgrading to a newer version.&lt;/li>
&lt;/ol></description></item><item><title>Guide to Apple Podcasts</title><link>https://en.1991421.cn/2025/05/06/guide-to-apple-podcasts/</link><pubDate>Tue, 06 May 2025 23:28:58 +0800</pubDate><guid>https://en.1991421.cn/2025/05/06/guide-to-apple-podcasts/</guid><description>&lt;blockquote>
&lt;p>I enjoy listening to podcasts before bed at night. Recently someone asked me how to use podcasts, so today I&amp;rsquo;m writing a guide to share my current usage patterns.&lt;/p>
&lt;/blockquote>
&lt;h2 id="apple-podcasts">
&lt;a class="heading-anchor-link" href="#apple-podcasts">Apple Podcasts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-podcasts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As an Apple ecosystem user, I use Apple Podcasts for podcasts. Currently Apple offers clients for the following platforms, and personally, I mainly use the iPhone version.&lt;/p>
&lt;ol>
&lt;li>Mac&lt;/li>
&lt;li>iPad&lt;/li>
&lt;li>iPhone&lt;/li>
&lt;li>Web version&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Note: Apple doesn&amp;rsquo;t offer a Windows client. If you&amp;rsquo;re a Windows user, you can either use the web version or third-party apps. If you know of any excellent podcast clients for Windows/Android, feel free to share in the comments.&lt;/strong>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-08-205933.jpeg"
alt="https://static.1991421.cn/2025/2025-05-08-205933.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="favorite-podcast-channels">
&lt;a class="heading-anchor-link" href="#favorite-podcast-channels">Favorite Podcast Channels&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="favorite-podcast-channels"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>On Apple Podcasts, I frequently listen to the following channels:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://podcasts.apple.com/cn/podcast/%E5%86%85%E6%A0%B8%E6%81%90%E6%85%8C/id928916244" target="_blank" rel="noopener">Kernel Panic&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://podcasts.apple.com/cn/podcast/%E7%96%AF%E6%8A%95%E5%9C%88/id1088178402" target="_blank" rel="noopener">Crazy Investment Circle&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://podcasts.apple.com/cn/podcast/it-%E5%85%AC%E8%AE%BA/id747497890" target="_blank" rel="noopener">IT Public Discussion&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://podcasts.apple.com/cn/podcast/%E5%8A%A9%E7%9C%A0%E7%9B%B8%E5%A3%B0%E7%B2%BE%E9%80%89/id1568019093" target="_blank" rel="noopener">Guo Degang&amp;rsquo;s Crosstalk&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="audiobooks">
&lt;a class="heading-anchor-link" href="#audiobooks">Audiobooks?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="audiobooks"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Apple Podcasts still has limited resources. If you can&amp;rsquo;t find what you&amp;rsquo;re looking for in the client, you can also search on YouTube. Combined with YouTube&amp;rsquo;s premium feature - background playback, it actually works quite well. For example, I often use YouTube to listen to comedy sketches/&amp;ldquo;Ghost Blows Out the Light&amp;rdquo; novels.&lt;/p>
&lt;h2 id="creating-podcasts-with-notebooklm-audio">
&lt;a class="heading-anchor-link" href="#creating-podcasts-with-notebooklm-audio">Creating Podcasts with notebooklm-audio&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="creating-podcasts-with-notebooklm-audio"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you&amp;rsquo;ve been playing with notebooklm recently, you can combine it with podcasts in new ways. notebooklm can convert articles/YouTube videos/PDFs, etc., into audio. Here&amp;rsquo;s the complete workflow:&lt;/p>
&lt;ol>
&lt;li>First, create a new notebook in notebooklm and upload a book PDF or a webpage.&lt;/li>
&lt;li>Click to generate audio.&lt;/li>
&lt;li>Download the audio, upload it to cloud storage or a file server, and get a remote access link.&lt;/li>
&lt;li>Build a podcast RSS feed - I&amp;rsquo;ve created an example here: &lt;a href="https://raw.githubusercontent.com/alanhe421/my-podcast/refs/heads/main/feed.xml" target="_blank" rel="noopener">Access Link&lt;/a>&lt;/li>
&lt;li>Add the RSS link in Apple Podcasts, click subscribe, and you&amp;rsquo;ll find it works when you click play.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>As you can see, creating your own podcast isn&amp;rsquo;t difficult. Of course, if you want to publish it officially in the store, the process will be different.&lt;/strong>&lt;/p>
&lt;h2 id="latest-notebooklm-news">
&lt;a class="heading-anchor-link" href="#latest-notebooklm-news">Latest notebooklm News&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="latest-notebooklm-news"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The iOS app version is expected to be released this month. With it, the conversion work mentioned above won&amp;rsquo;t be necessary, giving us another way to listen to podcasts.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-08-205531.jpeg"
alt="https://static.1991421.cn/2025/2025-05-08-205531.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In summary, podcasts are a pure way to listen to audio content. If you haven&amp;rsquo;t tried them before, give it a shot - maybe you&amp;rsquo;ll enjoy it.&lt;/p></description></item><item><title>Streamlining WeChat Official Account Article Editing</title><link>https://en.1991421.cn/2025/05/06/wechat-article-editing/</link><pubDate>Tue, 06 May 2025 22:32:39 +0800</pubDate><guid>https://en.1991421.cn/2025/05/06/wechat-article-editing/</guid><description>&lt;blockquote>
&lt;p>I&amp;rsquo;ve been running my WeChat official account again for the past two months and have summarized some efficiency tips for WeChat article editing to share with everyone.&lt;/p>
&lt;/blockquote>
&lt;h2 id="third-party-wechat-markdown-editor">
&lt;a class="heading-anchor-link" href="#third-party-wechat-markdown-editor">Third-Party WeChat Markdown Editor&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="third-party-wechat-markdown-editor"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The official editor is user-unfriendly and full of bugs. To improve efficiency and article formatting aesthetics, I recommend a free online &lt;a href="https://md.doocs.org/" target="_blank" rel="noopener">Markdown editor&lt;/a> that you can access directly. If you encounter a white screen when accessing it, it&amp;rsquo;s likely a network issue. Try resolving network problems, or if that doesn&amp;rsquo;t work, you can clone the project directly for private deployment.&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/doocs/md" target="_blank" rel="noopener">GitHub Repository&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://gitee.com/doocs/md" target="_blank" rel="noopener">Gitee Repository&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://gitcode.com/doocs/md" target="_blank" rel="noopener">GitCode Repository&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="editor-configuration-settings">
&lt;a class="heading-anchor-link" href="#editor-configuration-settings">Editor Configuration Settings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="editor-configuration-settings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When actually using the above editor, there are some settings I personally think you should enable to make articles more user-friendly.&lt;/p>
&lt;ol>
&lt;li>Convert external WeChat links to bottom references&lt;/li>
&lt;li>Display word count and reading time statistics&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-06-223817.jpeg"
alt="https://static.1991421.cn/2025/2025-05-06-223817.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="inserting-official-account-cards">
&lt;a class="heading-anchor-link" href="#inserting-official-account-cards">Inserting Official Account Cards&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="inserting-official-account-cards"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In many WeChat official account articles, you&amp;rsquo;ll see account cards that better encourage user subscriptions. How do you implement this in this editor? Here&amp;rsquo;s the method.&lt;/p>
&lt;p>When editing articles, paste the following code at the end of your article in the editor. When you copy the entire article to the WeChat official editor, it will recognize the corresponding account and you can click to convert it.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">---
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">section&lt;/span> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;margin-bottom: 0px;letter-spacing: 0.578px;text-align: center;&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">strong&lt;/span> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;letter-spacing: 0.578px;text-align: center;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;gt;&amp;lt;&lt;/span>&lt;span class="nt">span&lt;/span> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;font-size: 12px;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;gt;&amp;lt;&lt;/span>&lt;span class="nt">span&lt;/span> &lt;span class="na">leaf&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;gt;&lt;/span>若对你有所帮助，欢迎关注、分享、点赞及评论区留言👇👇👇&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">span&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">span&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">strong&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">section&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">center&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">img&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;https://static.1991421.cn/weixin/qrcode_for_gh_16079cf16d77_258.jpg&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;width: 100px;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">center&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-06-224050.jpeg"
alt="https://static.1991421.cn/2025/2025-05-06-224050.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="pro-tip---text-snippet">
&lt;a class="heading-anchor-link" href="#pro-tip---text-snippet">Pro Tip - Text Snippet&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pro-tip---text-snippet"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>To conveniently add the official account card to the end of every article, I use Alfred snippets to save the above code fragment with the keyword &lt;code>wxcard&lt;/code>. This way, typing &lt;code>wxcard&lt;/code> in the editor automatically expands to the account card code.
You can also achieve similar functionality with Apple&amp;rsquo;s built-in text replacement or Raycast.&lt;/p>
&lt;h2 id="daily-editing-workflow">
&lt;a class="heading-anchor-link" href="#daily-editing-workflow">Daily Editing Workflow&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="daily-editing-workflow"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After introducing the key techniques above, the entire workflow is summarized as follows:&lt;/p>
&lt;ol>
&lt;li>Edit MD articles locally&lt;/li>
&lt;li>Copy to third-party editor and click copy&lt;/li>
&lt;li>Paste into official WeChat account editor&lt;/li>
&lt;li>Click preview, check on mobile, and publish according to schedule once confirmed&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>These are my efficiency tips for WeChat official account editing. I welcome everyone to discuss together. I hope this helps you.&lt;/p></description></item><item><title>How to Read Source Code</title><link>https://en.1991421.cn/2025/05/06/how-to-read-source-code/</link><pubDate>Tue, 06 May 2025 15:17:32 +0800</pubDate><guid>https://en.1991421.cn/2025/05/06/how-to-read-source-code/</guid><description>&lt;blockquote>
&lt;p>I recently read an article - &lt;a href="https://github.com/aredridel/how-to-read-code/blob/master/how-to-read-code.md" target="_blank" rel="noopener">How To Read Source Code&lt;/a>. I deeply resonated with it, so I&amp;rsquo;m marking down my thoughts here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="purpose-of-reading-source-code">
&lt;a class="heading-anchor-link" href="#purpose-of-reading-source-code">Purpose of Reading Source Code&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purpose-of-reading-source-code"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Solving needs, for example, I look at inshellisense to solve auto-completion development needs, check click to component to solve JB IDE support issues. In short, you can&amp;rsquo;t talk about secondary development based on source code without reading it.&lt;/li>
&lt;li>Besides solving needs, you can also understand these experts&amp;rsquo; design thinking, even their coding styles.&lt;/li>
&lt;/ul>
&lt;h2 id="should-you-read-source-code">
&lt;a class="heading-anchor-link" href="#should-you-read-source-code">Should You Read Source Code?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="should-you-read-source-code"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Having mentioned the benefits above, naturally you should. Free code, free learning opportunities - not reading would be a waste.&lt;/p>
&lt;h2 id="ways-to-read-source-code">
&lt;a class="heading-anchor-link" href="#ways-to-read-source-code">Ways to Read Source Code&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ways-to-read-source-code"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I personally think there&amp;rsquo;s no fixed way to read code. For example, understanding parts of code through unit tests is fine, running the project is also fine, etc. There are many methods. Of course, the best way is if you can submit a PR, because the prerequisite for submitting a PR is that you probably understand how the entire project runs.&lt;/p>
&lt;p>For myself, I&amp;rsquo;ve previously contributed PRs to several open source projects. For example:&lt;/p>
&lt;ol>
&lt;li>&lt;a href="https://github.com/microsoft/inshellisense" target="_blank" rel="noopener">inshellisense&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/ericclemmons/click-to-component/pull/98" target="_blank" rel="noopener">click to component&lt;/a>&lt;/li>
&lt;/ol>
&lt;h2 id="no-time-to-read-source-code">
&lt;a class="heading-anchor-link" href="#no-time-to-read-source-code">No Time to Read Source Code?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="no-time-to-read-source-code"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I used to make this cognitive error too, not reading source code for many years. I personally think if a coder doesn&amp;rsquo;t have time to read source code, that means they&amp;rsquo;re quite unsuccessful, probably just busy with meaningless work.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In short, try reading more source code - it&amp;rsquo;s all benefits. Let&amp;rsquo;s encourage each other.&lt;/p></description></item><item><title>Trip to Baotou, Inner Mongolia</title><link>https://en.1991421.cn/2025/05/04/travel-baotou/</link><pubDate>Sun, 04 May 2025 22:33:21 +0800</pubDate><guid>https://en.1991421.cn/2025/05/04/travel-baotou/</guid><description>&lt;blockquote>
&lt;p>For the May Day holiday, I wanted somewhere convenient and uncrowded — ended up choosing Baotou. Some friends asked why; to me, travel is about going places I haven’t been. Notes from the trip.&lt;/p>
&lt;/blockquote>
&lt;h2 id="transportation">
&lt;a class="heading-anchor-link" href="#transportation">Transportation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="transportation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Beijing → Baotou is easy by high‑speed rail. Taxi to Beijing North (~30 minutes), then a bit over 3 hours to Baotou. Convenient, though the usual on‑train noise was unavoidable.&lt;/p>
&lt;h2 id="accommodation">
&lt;a class="heading-anchor-link" href="#accommodation">Accommodation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accommodation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>We stayed at Hanting. Over May Day, it was inexpensive — ~¥200+ with breakfast — booked 5 days, 4 nights.&lt;/p>
&lt;p>To save costs, compare Ctrip/Meituan/QuNar. My final booking on QuNar was cheaper than Ctrip by a few dozen yuan.&lt;/p>
&lt;p>Trade‑offs: Hanting’s soundproofing isn’t great; All Seasons left a better impression. Still, buffet breakfast was decent, time‑ and cost‑effective, and service acceptable. We did switch rooms once to avoid street noise.&lt;/p>
&lt;h2 id="food">
&lt;a class="heading-anchor-link" href="#food">Food&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="food"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Tried some things I don’t usually get:&lt;/p>
&lt;ol>
&lt;li>Shaomai — better than the “Inner Mongolia shaomai” I’ve had in Beijing&lt;/li>
&lt;li>Roasted milk skin — dairy is strong in Inner Mongolia; lots of variety&lt;/li>
&lt;li>Tea soup&lt;/li>
&lt;li>Stew dishes&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-04-225539.jpeg"
alt="https://static.1991421.cn/2025/2025-05-04-225539.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Overall prices were reasonable — didn’t spend much on food.&lt;/p>
&lt;h2 id="sights">
&lt;a class="heading-anchor-link" href="#sights">Sights&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="sights"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I don’t drive, so we mostly took taxis, which limits flexibility. Highlights:&lt;/p>
&lt;ol>
&lt;li>赛汗塔拉城中草原&lt;/li>
&lt;li>包头博物馆
&lt;ul>
&lt;li>去玩博物馆一定要注意是否需要预约和开放时间，比如包头博物馆免费，开放时间：每周二至周日，周一闭馆。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>赵北长城遗址&lt;/li>
&lt;li>湿地公园&lt;/li>
&lt;li>世界鹿园&lt;/li>
&lt;li>黄河大集&lt;/li>
&lt;li>北方兵器城&lt;/li>
&lt;/ol>
&lt;p>We also wandered through several city parks. I enjoy slow, aimless walks in the streets.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-04-230902.jpeg"
alt="https://static.1991421.cn/2025/2025-05-04-230902.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="is-baotou-uncrowded">
&lt;a class="heading-anchor-link" href="#is-baotou-uncrowded">Is Baotou uncrowded?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="is-baotou-uncrowded"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>During my stay, it felt relatively uncrowded — rarely saw throngs. A taxi driver said that over May Day, “ten leave Baotou, two come in.” It’s an industrial city, not a tourist city. Also, Inner Mongolia’s population is ~20+ million — similar to Beijing’s — but Baotou’s population is only a few million, with a land area larger than Beijing by 10k+ km².&lt;/p>
&lt;p>So yes, fewer people — which I enjoyed: fewer lines and less noise.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Baotou was great; I’d come again. Driving would help — taxis aren’t always convenient. Time to finally get comfortable behind the wheel this year; waiting on a license plate forever isn’t a plan.&lt;/p></description></item><item><title>Getting the DJI Osmo Mobile 7P Smartphone Stabilizer</title><link>https://en.1991421.cn/2025/04/28/osmo-mobile-7p/</link><pubDate>Mon, 28 Apr 2025 12:00:50 +0800</pubDate><guid>https://en.1991421.cn/2025/04/28/osmo-mobile-7p/</guid><description>&lt;blockquote>
&lt;p>With an upcoming trip in mind and knowing how shaky handheld smartphone footage can be, I decided to pick up the DJI Osmo Mobile 7P. Here are my thoughts and experiences after using it for a few weeks.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-03-093337.jpeg"
alt="DJI Osmo Mobile 7P"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="osmo-vs-pocket-3">
&lt;a class="heading-anchor-link" href="#osmo-vs-pocket-3">Osmo vs. Pocket 3&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="osmo-vs-pocket-3"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I initially looked at the Pocket 3, but it had a few drawbacks for my specific use case:&lt;/p>
&lt;ol>
&lt;li>While the Pocket 3 is superior for video, it’s not primarily a still camera.&lt;/li>
&lt;li>Since I always carry my phone anyway, the Pocket 3 felt redundant for photography.&lt;/li>
&lt;/ol>
&lt;p>Ultimately, I just wanted my phone to be easier to use for selfies and more stable for video. The DJI stabilizer fits perfectly as a supplementary accessory to my existing gear.&lt;/p>
&lt;h2 id="why-the-7p">
&lt;a class="heading-anchor-link" href="#why-the-7p">Why the 7P?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-the-7p"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The 7P is the latest model. Priced under 1,000 CNY, it follows the &amp;ldquo;buy the newest&amp;rdquo; philosophy. With its built-in extension rod and tripod, it’s a solid, all-in-one choice.&lt;/p>
&lt;p>I bought mine through Pinduoduo&amp;rsquo;s &amp;ldquo;Billions in Subsidies&amp;rdquo; program for &lt;strong>799 CNY&lt;/strong>. JD and the official store were priced at &lt;strong>899 CNY&lt;/strong>, which felt a bit steep. As long as authenticity is guaranteed, I go with the lower price.&lt;/p>
&lt;h2 id="dji-care-refresh">
&lt;a class="heading-anchor-link" href="#dji-care-refresh">DJI Care Refresh&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="dji-care-refresh"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>DJI offers a protection plan for its products, with prices varying by device.&lt;/li>
&lt;li>Unless you have a specific reason not to, I highly recommend buying it—these are delicate electronics. I purchased the 2-year plan the day I got my 7P and plan to renew it if possible.&lt;/li>
&lt;/ol>
&lt;p>&lt;em>Note: You can purchase Care Refresh for a maximum total of 3 consecutive years.&lt;/em>&lt;/p>
&lt;h2 id="essential-accessories">
&lt;a class="heading-anchor-link" href="#essential-accessories">Essential Accessories?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="essential-accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>The 7P comes with enough basic accessories. I don&amp;rsquo;t recommend buying extras unless you have a very specific need.&lt;/li>
&lt;li>I specifically advise against the &lt;code>DJI OM Magnetic Phone Clamp&lt;/code>. Its biggest flaw is that it’s incompatible with the tracking module.&lt;/li>
&lt;/ol>
&lt;h2 id="usage-tips">
&lt;a class="heading-anchor-link" href="#usage-tips">Usage Tips&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage-tips"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Watch the tutorials.&lt;/strong> I can&amp;rsquo;t stress this enough. If you find it hard to use, you probably haven&amp;rsquo;t watched the guide.&lt;/li>
&lt;li>&lt;strong>Tracking in other apps&lt;/strong>: You can use the tracking feature during WeChat video calls by pressing the trigger button to start tracking.&lt;/li>
&lt;/ol>
&lt;h2 id="impressions-after-several-weeks">
&lt;a class="heading-anchor-link" href="#impressions-after-several-weeks">Impressions After Several Weeks&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="impressions-after-several-weeks"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Built-in Extension &amp;amp; Tripod&lt;/strong>: These solve real-world pain points.&lt;/li>
&lt;li>&lt;strong>Build Quality&lt;/strong>: The craftsmanship and interaction design are excellent. The auto-tracking feature is incredibly convenient.&lt;/li>
&lt;li>&lt;strong>Fill Light&lt;/strong>: The optional fill light accessory is fantastic for night shots.&lt;/li>
&lt;li>&lt;strong>Learning Curve&lt;/strong>: With the tutorials in the DJI Mimo app, it’s easy to get the hang of the button shortcuts.&lt;/li>
&lt;/ol>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>App Stability&lt;/strong>: The DJI Mimo app can be flaky. I’ve been logged out unexpectedly several times.&lt;/li>
&lt;li>&lt;strong>Bulk&lt;/strong>: It’s relatively large, making it a bit cumbersome to carry compared to the Pocket series. However, given the built-in tripod/rod, it&amp;rsquo;s a fair trade-off.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>This is my first DJI product, and I’m impressed. I recommend anyone interested in mobile photography to give DJI a try—whether it&amp;rsquo;s a gimbal or another device depends on your needs. I’m already planning to pick up a Pocket and a drone in the future.&lt;/p>
&lt;h2 id="related-links">
&lt;a class="heading-anchor-link" href="#related-links">Related Links&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-links"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.dji.com/cn/osmo-mobile-7-series/video" target="_blank" rel="noopener">Official DJI Osmo Mobile 7 Series Tutorials&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Applying for a Wise Account</title><link>https://en.1991421.cn/2025/04/22/4d28d67/</link><pubDate>Tue, 22 Apr 2025 09:55:24 +0800</pubDate><guid>https://en.1991421.cn/2025/04/22/4d28d67/</guid><description>&lt;blockquote>
&lt;p>I recently needed to accept overseas payments via Wise, so I walked through the setup process—documenting it here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="create-an-account">
&lt;a class="heading-anchor-link" href="#create-an-account">Create an account&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="create-an-account"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Head to the Wise website &lt;a href="https://wise.com/" target="_blank" rel="noopener">https://wise.com/&lt;/a> and follow the prompts to sign up. When asked for your country, choose Mainland China—you can change it later if needed.&lt;/p>
&lt;ul>
&lt;li>Mainland China accounts support parts of the Wise offering, such as receiving funds, but debit cards aren’t available.&lt;/li>
&lt;li>To change your account’s country later, go to &lt;a href="https://wise.com/edit-personal-details?redirectUrl=%2Fyour-account%2Fpersonal-details" target="_blank" rel="noopener">this Wise page&lt;/a>.&lt;/li>
&lt;/ul>
&lt;h2 id="account-verification">
&lt;a class="heading-anchor-link" href="#account-verification">Account verification&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="account-verification"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Submit your passport photo page and a selfie as instructed. I scanned the QR code shown on the desktop site with WeChat, followed the prompts to take the photos, and uploaded them. The review was fast—approved the same day.&lt;/p>
&lt;h2 id="receiving-payments">
&lt;a class="heading-anchor-link" href="#receiving-payments">Receiving payments&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="receiving-payments"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Add accounts for the currencies you need inside Wise; it will then provide the relevant bank details for incoming payments.&lt;/p></description></item><item><title>Getting the iPad 11</title><link>https://en.1991421.cn/2025/04/12/ipad11/</link><pubDate>Sat, 12 Apr 2025 11:58:50 +0800</pubDate><guid>https://en.1991421.cn/2025/04/12/ipad11/</guid><description>&lt;blockquote>
&lt;p>I picked up the 11-inch iPad a few days ago. It&amp;rsquo;s an entry-level tablet, but it&amp;rsquo;s more than enough for me right now. After using it for a bit, I&amp;rsquo;m jotting down my impressions.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-04-12-121258.jpeg"
alt="https://static.1991421.cn/2025/2025-04-12-121258.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="why-i-bought-it">
&lt;a class="heading-anchor-link" href="#why-i-bought-it">Why I Bought It&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-i-bought-it"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>My iPad mini 5 is already six years old, and it can no longer receive system updates. Some apps have stopped working as well, so I took advantage of a government subsidy to upgrade my device.&lt;/p>
&lt;h2 id="purchase">
&lt;a class="heading-anchor-link" href="#purchase">Purchase&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchase"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When it comes to 3C products in China, JD.com is my go-to choice.&lt;/p>
&lt;p>This time I stacked the government subsidy with the education discount and chose the iPad with the A16 chip, Wi-Fi, 128 GB of storage, and the silver-gray finish. It cost &lt;code>2379.15 CNY&lt;/code>, down from the original &lt;code>2999 CNY&lt;/code>.&lt;/p>
&lt;p>&lt;code>I see the subsidy as direct cash back, so for small electronics it's worth prioritizing.&lt;/code>&lt;/p>
&lt;h2 id="accessories">
&lt;a class="heading-anchor-link" href="#accessories">Accessories&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>So far I&amp;rsquo;ve only bought a tempered glass screen protector. I skipped the case for two reasons: the iPad isn&amp;rsquo;t that expensive, so I don&amp;rsquo;t feel the need to baby it, and I don&amp;rsquo;t want the extra weight.&lt;/p>
&lt;ul>
&lt;li>Flash Demon tempered glass screen protector&lt;/li>
&lt;/ul>
&lt;h2 id="initial-impressions">
&lt;a class="heading-anchor-link" href="#initial-impressions">Initial Impressions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="initial-impressions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After using it for a few days, here&amp;rsquo;s what stands out.&lt;/p>
&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The screen is plenty large (coming from the mini, the size difference is obvious).&lt;/li>
&lt;/ol>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The display quality is visibly mediocre, but that&amp;rsquo;s expected at this price. If you&amp;rsquo;re picky about screens, I don&amp;rsquo;t recommend the standard iPad.&lt;/li>
&lt;li>There&amp;rsquo;s no Face ID. I&amp;rsquo;m so used to unlocking my iPhone this way that it&amp;rsquo;ll take some getting used to.&lt;/li>
&lt;/ol>
&lt;h2 id="setting-up-the-ipad">
&lt;a class="heading-anchor-link" href="#setting-up-the-ipad">Setting Up the iPad&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="setting-up-the-ipad"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Since it&amp;rsquo;s a new device, I found the overall Apple experience to be excellent. Place the two iPads next to each other, transfer the data wirelessly, and once it&amp;rsquo;s done the new iPad has a full copy of the old one. Just sign into your Apple ID and you&amp;rsquo;re good to go—it saves a lot of hassle.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Overall, getting an 11-inch iPad for just over 2,000 yuan feels like a solid value. Combined with the Apple ecosystem experience, I&amp;rsquo;m very satisfied.&lt;/p></description></item><item><title>Troubleshooting Apple Universal Clipboard Issues</title><link>https://en.1991421.cn/2025/04/03/apple/</link><pubDate>Thu, 03 Apr 2025 17:30:25 +0800</pubDate><guid>https://en.1991421.cn/2025/04/03/apple/</guid><description>&lt;p>Like many of you, I rely on Apple&amp;rsquo;s cross-device clipboard synchronization. Recently, I encountered an issue where copying between my office Mac and iPhone wasn&amp;rsquo;t working - neither device could directly cloud copy to the other. After some investigation, I finally resolved it. I&amp;rsquo;m marking it down here, which might help others.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-04-03-174239.jpeg"
alt="https://static.1991421.cn/2025/2025-04-03-174239.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="symptoms">
&lt;a class="heading-anchor-link" href="#symptoms">Symptoms&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="symptoms"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Copying between my office Mac and iPhone wasn&amp;rsquo;t working. For example, when copying text on a Mac, the iPhone couldn&amp;rsquo;t detect it, and vice versa. This was particularly frustrating when I needed to quickly transfer a piece of text from one device to another.&lt;/p>
&lt;h2 id="issue-identification">
&lt;a class="heading-anchor-link" href="#issue-identification">Issue Identification&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="issue-identification"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since I have several Macs at home, I tested with them as well. For instance, the clipboard sync between my home Mac mini and iPhone worked fine, which indicated that the iPhone was working correctly. Therefore, I could confirm that the issue was explicitly with my office Mac.&lt;/p>
&lt;p>Based on this observation, it became clear that when a single device has an issue, it affects both sending and receiving copies.&lt;/p>
&lt;h2 id="attempted-fix-methods">
&lt;a class="heading-anchor-link" href="#attempted-fix-methods">Attempted Fix Methods&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="attempted-fix-methods"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After looking through many tutorials online, here are the practical solutions I found:&lt;/p>
&lt;ol>
&lt;li>For Mac or any other Apple device, ensure Wi-Fi/Bluetooth/Handoff are all enabled.&lt;/li>
&lt;li>Verify that all devices are signed in to the same iCloud account. Note that the iCloud account can be different from the AppStore account.&lt;/li>
&lt;/ol>
&lt;h2 id="issue-fixed">
&lt;a class="heading-anchor-link" href="#issue-fixed">Issue Fixed&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="issue-fixed"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In my case, the issue was resolved after trying the above methods. The problem was caused by switching the Mac&amp;rsquo;s iCloud account at some point, and signing out and back in fixed it.&lt;/p>
&lt;h2 id="how-universal-clipboard-works">
&lt;a class="heading-anchor-link" href="#how-universal-clipboard-works">How Universal Clipboard Works&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-universal-clipboard-works"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>While solving this, let&amp;rsquo;s understand why these methods were necessary:&lt;/p>
&lt;ol>
&lt;li>Apple&amp;rsquo;s Handoff feature itself uses Wi-Fi and Bluetooth. Clipboard synchronization is one application of Handoff.&lt;/li>
&lt;li>iCloud handles authentication, ensuring that only your devices can transfer data between each other.&lt;/li>
&lt;/ol>
&lt;h2 id="at-the-end">
&lt;a class="heading-anchor-link" href="#at-the-end">At the end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="at-the-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Apple&amp;rsquo;s software services aren&amp;rsquo;t without bugs; when problems arise, we can only analyze and solve them patiently. However, the Apple Universal Clipboard is a powerful feature that, despite occasional issues, is highly recommended for Apple ecosystem users with multiple Apple devices to try out.&lt;/p></description></item><item><title>Tips about how to use highlight.js</title><link>https://en.1991421.cn/2025/03/25/highlight-js/</link><pubDate>Tue, 25 Mar 2025 23:43:22 +0800</pubDate><guid>https://en.1991421.cn/2025/03/25/highlight-js/</guid><description>&lt;blockquote>
&lt;p>While developing &lt;a href="https://marketplace.visualstudio.com/items?itemName=AlanHe.cn-alanhe-gitlink" target="_blank" rel="noopener">GitLink&lt;/a>, I needed code highlighting functionality, so I researched highlight.js and discovered some implementation details worth noting.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-03-25-235551.jpeg"
alt="https://static.1991421.cn/2025/2025-03-25-235551.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="import-highlightjs">
&lt;a class="heading-anchor-link" href="#import-highlightjs">Import highlight.js&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="import-highlightjs"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For web pages requiring CDN import or direct src import, you should not use highlight.js resources directly, but rather use &lt;code>highlightjs/cdn-release&lt;/code>.&lt;/p>
&lt;p>For projects involving build tools, you should use the npm package of &lt;code>highlight.js&lt;/code>.&lt;/p>
&lt;h2 id="language-registration">
&lt;a class="heading-anchor-link" href="#language-registration">Language Registration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="language-registration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Importing highlight.js doesn&amp;rsquo;t automatically register all languages supported by highlight.js. If you want to register all languages, you need to import and register them manually.&lt;/li>
&lt;li>Taking the highlight.js npm package as an example, in &lt;code>/highlight.js/es/languages/&lt;/code>, you can see all language files. To register all languages, you need to import all these language files.&lt;/li>
&lt;li>Besides official languages, you can also register custom languages. For example, some language packages provided in the official repo, such as &lt;a href="https://github.com/highlightjs/highlightjs-4d" target="_blank" rel="noopener">highlightjs-4d&lt;/a>&lt;/li>
&lt;/ol>
&lt;h2 id="auto-highlight">
&lt;a class="heading-anchor-link" href="#auto-highlight">Auto highlight&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="auto-highlight"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In addition to the highlight method, there&amp;rsquo;s also &lt;code>highlightAuto&lt;/code> for use when the language is uncertain.&lt;/p>
&lt;h2 id="display-line-numbers">
&lt;a class="heading-anchor-link" href="#display-line-numbers">Display Line Numbers&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="display-line-numbers"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>highlight.js doesn&amp;rsquo;t natively support line number display. You need to use third-party plugins for this functionality, such as &lt;a href="https://github.com/wcoder/highlightjs-line-numbers.js" target="_blank" rel="noopener">highlightjs-line-numbers.js&lt;/a>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>These are some issues I encountered while using highlight.js. There might be other considerations, and I welcome any discussion.&lt;/p></description></item><item><title>Implementing JSON Schema-based Intelligent Suggestions in Monaco Editor</title><link>https://en.1991421.cn/2025/03/19/monaco-editor-json-schema/</link><pubDate>Wed, 19 Mar 2025 16:53:42 +0800</pubDate><guid>https://en.1991421.cn/2025/03/19/monaco-editor-json-schema/</guid><description>&lt;blockquote>
&lt;p>Recently, while implementing a JSON data editor using Monaco editor, I discovered a method to implement JSON Schema-based intelligent suggestions to enhance user experience. Here&amp;rsquo;s what I learned.&lt;/p>
&lt;/blockquote>
&lt;h2 id="implementation">
&lt;a class="heading-anchor-link" href="#implementation">Implementation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="implementation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Using Monaco-editor&amp;rsquo;s language service to implement JSON Schema-based intelligent suggestions.&lt;/p>
&lt;h3 id="setting-up-json-schema">
&lt;a class="heading-anchor-link" href="#setting-up-json-schema">Setting up JSON Schema&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="setting-up-json-schema"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">monaco&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">languages&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">json&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">jsonDefaults&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">setDiagnosticsOptions&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">validate&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">schemas&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">uri&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;http://myschema/abi-schema.json&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fileMatch&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="nx">model&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">uri&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">toString&lt;/span>&lt;span class="p">()],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">schema&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;array&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">items&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;object&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">required&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">properties&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;string&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">description&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Function or event name&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;string&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">enum&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;function&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;event&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;constructor&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">description&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Type: function, event, or constructor&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">inputs&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;array&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">description&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Input parameters&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">items&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;object&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">properties&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;string&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">description&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Parameter name&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;string&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">description&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Parameter type&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="editor-options">
&lt;a class="heading-anchor-link" href="#editor-options">Editor options&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="editor-options"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">options&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">minimap&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">enabled&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">false&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">lineNumbers&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">quickSuggestions&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Auto-completion
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">autoIndent&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">automaticLayout&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">validate&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">folding&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">hover&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">enabled&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">suggest&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">insertMode&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;insert&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">showInlineDetails&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">showDetails&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">preview&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">previewMode&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;prefix&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">maxVisibleSuggestions&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">12&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>If you only need suggestions for specific editors, use fileMatch to restrict the scope; otherwise, it will trigger JSON suggestions in other editors.&lt;/li>
&lt;/ol>
&lt;h2 id="results">
&lt;a class="heading-anchor-link" href="#results">Results&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="results"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-03-19-170140.jpeg"
alt="https://static.1991421.cn/2025/2025-03-19-170140.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-03-19-170221.jpeg"
alt="https://static.1991421.cn/2025/2025-03-19-170221.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="at-the-end">
&lt;a class="heading-anchor-link" href="#at-the-end">At the end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="at-the-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>We now understand how to implement code suggestions for fixed JSON data types in Monaco editor.&lt;/p></description></item><item><title>Getting the MacBook Air M4</title><link>https://en.1991421.cn/2025/03/19/macbook-air-m4/</link><pubDate>Wed, 19 Mar 2025 15:31:38 +0800</pubDate><guid>https://en.1991421.cn/2025/03/19/macbook-air-m4/</guid><description>&lt;blockquote>
&lt;p>I recently picked up a MacBook Air M4. After a few days of use, I’m quite happy with it, so here are some quick notes on my experience.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-03-22-075536.jpeg"
alt="https://static.1991421.cn/2025/2025-03-22-075536.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="why-i-bought-it">
&lt;a class="heading-anchor-link" href="#why-i-bought-it">Why I Bought It&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-i-bought-it"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I already have a Mac mini as my non-work machine, but I was missing a truly portable laptop. I don’t plan to use it as my primary device — more as a “just in case” backup. With that goal and budget in mind, I decided on a MacBook.&lt;/p>
&lt;h2 id="purchase">
&lt;a class="heading-anchor-link" href="#purchase">Purchase&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchase"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>For 3C purchases in China, JD is the default choice.&lt;/strong>&lt;/p>
&lt;p>This time I used the national subsidy plus the education discount to get a 13-inch MacBook Air M4 with 16 GB RAM and a 256 GB SSD for &lt;code>5799 CNY&lt;/code> (down from &lt;code>7999 CNY&lt;/code>).&lt;/p>
&lt;h2 id="accessories">
&lt;a class="heading-anchor-link" href="#accessories">Accessories&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I already have plenty of accessories, so I’m mostly reusing what I own. The only new addition so far:&lt;/p>
&lt;ol>
&lt;li>Tempered glass screen protector (&lt;code>recommended&lt;/code>)&lt;/li>
&lt;/ol>
&lt;h2 id="initial-impressions">
&lt;a class="heading-anchor-link" href="#initial-impressions">Initial Impressions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="initial-impressions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Compared with the Mac mini, the MBA isn’t exactly the “value king” in my view, and its pros and cons are quite clear.&lt;/p>
&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Sensible base configuration. M4 + 16 GB RAM is plenty for everyday use.&lt;/li>
&lt;li>The new sky-blue color really does look nice.&lt;/li>
&lt;li>Compared with the Pro, being lighter is never a bad thing — it’s genuinely appealing.&lt;/li>
&lt;/ol>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Only two Thunderbolt ports, both on the left side, which means no charging from the right — inconvenient.&lt;/li>
&lt;li>Storage is small at 256 GB. That’s on me for budget reasons, haha — but it’s actually fine for my use.&lt;/li>
&lt;li>The included 30 W charger is underwhelming; I prefer using Anker or ThinkPlus chargers day-to-day.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Overall, getting an M4 MacBook Air for under 6,000 CNY is great value. It meets my needs for mobile work and light development.&lt;/p></description></item><item><title>How to Use Stripe (Step-by-Step Guide)</title><link>https://en.1991421.cn/2025/03/12/stripe/</link><pubDate>Wed, 12 Mar 2025 20:22:50 +0800</pubDate><guid>https://en.1991421.cn/2025/03/12/stripe/</guid><description>&lt;blockquote>
&lt;p>Medium’s MPP and GitHub Sponsors both use Stripe for payouts and payments. Here are a few Stripe notes and fixes I’ve run into.&lt;/p>
&lt;/blockquote>
&lt;h2 id="common-questions">
&lt;a class="heading-anchor-link" href="#common-questions">Common Questions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-questions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="change-the-dashboard-display-language">
&lt;a class="heading-anchor-link" href="#change-the-dashboard-display-language">Change the dashboard display language&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="change-the-dashboard-display-language"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Press &lt;code>⌘ K&lt;/code> to open the search bar, type &lt;code>language&lt;/code>, and jump to the language settings page.&lt;/p>
&lt;p>&lt;a href="https://dashboard.stripe.com/settings/user" target="_blank" rel="noopener">https://dashboard.stripe.com/settings/user&lt;/a>&lt;/p>
&lt;h2 id="close-an-account">
&lt;a class="heading-anchor-link" href="#close-an-account">Close an account&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="close-an-account"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Open the settings page and choose “Close account”.
&lt;a href="https://dashboard.stripe.com/settings/account" target="_blank" rel="noopener">https://dashboard.stripe.com/settings/account&lt;/a>&lt;/p></description></item><item><title>CNCB Offline Mortgage Prepayment</title><link>https://en.1991421.cn/2025/03/07/6450633/</link><pubDate>Fri, 07 Mar 2025 20:11:24 +0800</pubDate><guid>https://en.1991421.cn/2025/03/07/6450633/</guid><description>&lt;blockquote>
&lt;p>I’ve always used CNCB’s app to book mortgage prepayments. The rule there is: no pending prepayment and a 30‑day advance reservation. I saw talk that offline prepayment might bypass the 30‑day wait, so I tried it — and it worked. Here’s what I did.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-04-04-112428.jpeg"
alt="https://static.1991421.cn/2025/2025-04-04-112428.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="first-try-ask-the-loan-manager-about-offline-prepayment">
&lt;a class="heading-anchor-link" href="#first-try-ask-the-loan-manager-about-offline-prepayment">First try: ask the loan manager about offline prepayment&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="first-try-ask-the-loan-manager-about-offline-prepayment"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The manager said offline also requires 30 days — no early prepayment.&lt;/p>
&lt;h2 id="file-a-complaint-via-12378">
&lt;a class="heading-anchor-link" href="#file-a-complaint-via-12378">File a complaint via 12378&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="file-a-complaint-via-12378"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Call &lt;code>12378&lt;/code> to file a complaint. CNCB will contact you. Clearly state your request: offline prepayment without waiting 30 days.&lt;/p>
&lt;h2 id="process-for-offline-prepayment">
&lt;a class="heading-anchor-link" href="#process-for-offline-prepayment">Process for offline prepayment&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="process-for-offline-prepayment"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Go to the designated branch and take a number.
&lt;ul>
&lt;li>Bring your &lt;code>ID card&lt;/code>.&lt;/li>
&lt;li>Must be a &lt;code>business day&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>At the counter, state your request. If they insist on a 30‑day reservation, say you’ve already filed a 12378 complaint and are dissatisfied. They will provide an application form.&lt;/li>
&lt;li>Fill out the form; staff will submit it for manager approval.
&lt;ul>
&lt;li>The prepayment amount only needs to be greater than your monthly payment; it does not need to be in ten‑thousand increments.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>After approval, deduction can happen the same day. The app will show a new prepayment request as “processing”; wait for the deduction.
&lt;ul>
&lt;li>I hit a snag: Friday after 4pm I was told “approved”, but deduction didn’t happen until Monday. The explanation was vague — likely someone forgot to process. Annoying, but the extra interest was small, so I let it go.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Regardless of others’ views on prepayment, I simply dislike owing money and paying interest. If you can afford it, keep prepaying. After two years, my bank loan is almost cleared; I’m down to about a hundred yuan per month — no pressure.&lt;/p></description></item><item><title>Animated PNGs</title><link>https://en.1991421.cn/2025/02/28/dynamic-png/</link><pubDate>Fri, 28 Feb 2025 15:02:36 +0800</pubDate><guid>https://en.1991421.cn/2025/02/28/dynamic-png/</guid><description>&lt;blockquote>
&lt;p>While using Tencent Docs today, I noticed this &lt;a href="https://docs.gtimg.com/docs_components/img/membership_nameplate_svip_14@3x.cfba4393b4f88878da9d.png" target="_blank" rel="noopener">VIP badge&lt;/a> image. The URL ends with &lt;code>.png&lt;/code>, yet it&amp;rsquo;s animated. I always thought PNGs were static, so I dug around and learned that PNGs can, in fact, be animated. Here&amp;rsquo;s a quick summary to fill that knowledge gap.&lt;/p>
&lt;/blockquote>
&lt;h2 id="animated-pngs">
&lt;a class="heading-anchor-link" href="#animated-pngs">Animated PNGs&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="animated-pngs"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The proper term is &lt;code>APNG&lt;/code>.&lt;/p>
&lt;ol>
&lt;li>The file extension remains &lt;code>.png&lt;/code>.&lt;/li>
&lt;li>The MIME type is still &lt;code>image/png&lt;/code>.&lt;/li>
&lt;li>PNG supports a &lt;code>transparent channel&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>In other words, you can&amp;rsquo;t distinguish static PNGs from animated ones just by looking at the file metadata.&lt;/p>
&lt;h2 id="png-vs-webp">
&lt;a class="heading-anchor-link" href="#png-vs-webp">PNG vs. WebP&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="png-vs-webp"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Besides PNG, we often use WebP for animated images. WebP files tend to be smaller, so if the browser supports it, WebP is usually the better choice.&lt;/p>
&lt;h2 id="example">
&lt;a class="heading-anchor-link" href="#example">Example&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="example"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Let&amp;rsquo;s compare the Tencent Docs VIP badge in both formats.&lt;/p>
&lt;h3 id="webp">
&lt;a class="heading-anchor-link" href="#webp">WebP&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="webp"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/membership_nameplate_svip_14@3x.cfba4393b4f88878da9d.webp"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="png">
&lt;a class="heading-anchor-link" href="#png">PNG&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="png"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/ezgif-7d2efd1195964b.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Note: Tencent Docs auto-negotiates the best format. So even though the URL ends in &lt;code>.png&lt;/code>, modern browsers receive WebP data behind the scenes.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>That&amp;rsquo;s a quick primer on animated PNGs.&lt;/p></description></item><item><title>Getting the Mac mini M4</title><link>https://en.1991421.cn/2025/02/24/macmini4/</link><pubDate>Mon, 24 Feb 2025 18:52:36 +0800</pubDate><guid>https://en.1991421.cn/2025/02/24/macmini4/</guid><description>&lt;blockquote>
&lt;p>I recently picked up a Mac mini M4. After using it for a few weeks, I&amp;rsquo;m really happy with it, so I&amp;rsquo;m jotting down my impressions here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="why-i-bought-it">
&lt;a class="heading-anchor-link" href="#why-i-bought-it">Why I Bought It&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-i-bought-it"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>My only non-work computer was a 2019 MacBook Pro with 32 GB of RAM, but it&amp;rsquo;s sluggish and runs hot. To make tinkering more enjoyable, I decided to get a Mac mini.&lt;/p>
&lt;h2 id="purchase">
&lt;a class="heading-anchor-link" href="#purchase">Purchase&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchase"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>There aren&amp;rsquo;t many options for buying 3C products in China, so I went straight to JD for the national subsidy. Final price: &lt;code>6000 CNY&lt;/code> (originally &lt;code>7499 CNY&lt;/code>). The configuration is 24 GB of memory and a 512 GB SSD. I didn&amp;rsquo;t go higher because of budget constraints.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-02-24-191238.jpeg"
alt="https://static.1991421.cn/2025/2025-02-24-191238.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="accessories">
&lt;a class="heading-anchor-link" href="#accessories">Accessories&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I haven&amp;rsquo;t bought any new accessories yet—just using what I already have.&lt;/p>
&lt;ol>
&lt;li>Two Dell U-series monitors&lt;/li>
&lt;li>Filco 87 mechanical keyboard with red switches&lt;/li>
&lt;li>Logitech M720 mouse&lt;/li>
&lt;li>Microphone – XFAN D1 on-camera mic&lt;/li>
&lt;/ol>
&lt;h2 id="initial-impressions">
&lt;a class="heading-anchor-link" href="#initial-impressions">Initial Impressions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="initial-impressions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>The M4 is genuinely fast and runs cool.&lt;/li>
&lt;li>The small footprint is fantastic—it looks neat on the desk.&lt;/li>
&lt;li>Even though I bought the base configuration, it&amp;rsquo;s more than enough for light development.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>All in all, getting an M4 for 6,000 CNY feels like an excellent value.&lt;/p></description></item><item><title>Refresh Rate Explained (Simple Guide)</title><link>https://en.1991421.cn/2025/02/14/refresh-rate-intro/</link><pubDate>Fri, 14 Feb 2025 17:54:35 +0800</pubDate><guid>https://en.1991421.cn/2025/02/14/refresh-rate-intro/</guid><description>&lt;blockquote>
&lt;p>I’ve been looking into frontend animation jank, which is related to refresh rate. I looked up some basics about refresh rate and took notes here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="what-is-refresh-rate">
&lt;a class="heading-anchor-link" href="#what-is-refresh-rate">What is refresh rate&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-is-refresh-rate"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Refresh rate refers to how many images a display shows per second, measured in hertz (Hz). For example, my MBP is connected to a Dell monitor, and in the OS I can see the monitor’s current refresh rate.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-02-14-175909.jpeg"
alt="https://static.1991421.cn/2025/2025-02-14-175909.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="refresh-rates-humans-can-perceive">
&lt;a class="heading-anchor-link" href="#refresh-rates-humans-can-perceive">Refresh rates humans can perceive&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="refresh-rates-humans-can-perceive"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The human eye recognizes around 10–12 fps as continuous animation, 24 fps as cinema-level smoothness, and 60 fps as close to day-to-day “no perceptible latency.” Studies suggest our sensitivity to change can exceed 200 fps, especially when tracking fast-moving objects 589.&lt;/p>
&lt;h3 id="baseline-perception-thresholds">
&lt;a class="heading-anchor-link" href="#baseline-perception-thresholds">Baseline perception thresholds&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="baseline-perception-thresholds"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The human eye recognizes around 10–12 fps as continuous animation, 24 fps as cinema-level smoothness, and 60 fps as close to day-to-day “no perceptible latency.” Studies suggest our sensitivity to change can exceed 200 fps, especially when tracking fast-moving objects 589.&lt;/p>
&lt;h3 id="individual-and-scenario-differences">
&lt;a class="heading-anchor-link" href="#individual-and-scenario-differences">Individual and scenario differences&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="individual-and-scenario-differences"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>General users: 60–90 fps is already smooth enough; further improvements are harder to notice 610.&lt;/li>
&lt;li>Esports players: 144 fps and above improves capture of dynamic visual information. For example, many CS:GO pros use 240 Hz monitors to shorten reaction time 39.&lt;/li>
&lt;li>Motion blur: Fast motion in the real world naturally includes blur; high frame rates in games can better simulate this and increase immersion 711.&lt;/li>
&lt;/ul>
&lt;p>From this we can see that 60 Hz is very smooth, and rates above 60 are not meaningless—differences are perceptible in specific scenarios like gaming.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Looking at the budget iPhone in my hand, it might be time to upgrade—no high refresh support.&lt;/p></description></item><item><title>My Medium Earnings in 2024</title><link>https://en.1991421.cn/2025/02/13/2024medium/</link><pubDate>Thu, 13 Feb 2025 18:03:15 +0800</pubDate><guid>https://en.1991421.cn/2025/02/13/2024medium/</guid><description>&lt;blockquote>
&lt;p>In 2024, I resolved the issue with using Stripe for payments on Medium, so I subscribed to Medium membership at the beginning of the year and joined the MPP program to start writing. Here&amp;rsquo;s an analysis of my Medium earnings over the past year and my future direction.&lt;/p>
&lt;/blockquote>
&lt;p>Let me first show you the modest earnings.&lt;/p>
&lt;h2 id="earnings-overview">
&lt;a class="heading-anchor-link" href="#earnings-overview">Earnings Overview&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="earnings-overview"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-02-13-180909.jpeg"
alt="https://static.1991421.cn/2025/2025-02-13-180909.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Total earnings = $12.95&lt;/p>
&lt;h2 id="followers">
&lt;a class="heading-anchor-link" href="#followers">Followers&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="followers"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-02-13-181012.jpeg"
alt="https://static.1991421.cn/2025/2025-02-13-181012.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="article-reading-statistics">
&lt;a class="heading-anchor-link" href="#article-reading-statistics">Article Reading Statistics&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="article-reading-statistics"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here&amp;rsquo;s an example from &lt;code>December 2024&lt;/code> showing article reading performance.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-02-13-181254.jpeg"
alt="https://static.1991421.cn/2025/2025-02-13-181254.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="number-of-published-articles">
&lt;a class="heading-anchor-link" href="#number-of-published-articles">Number of Published Articles&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="number-of-published-articles"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As of now, I&amp;rsquo;ve published &lt;code>200+ articles&lt;/code> on Medium, including &lt;code>80+ English articles&lt;/code>.&lt;/p>
&lt;h2 id="data-analysis">
&lt;a class="heading-anchor-link" href="#data-analysis">Data Analysis&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="data-analysis"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>On average, I only earn about &lt;code>$1&lt;/code> per month, while Medium membership costs &lt;code>$5&lt;/code> per month.&lt;/li>
&lt;li>Comparing to article views, with just over &lt;code>a thousand&lt;/code> monthly views and reads, the numbers are quite low.&lt;/li>
&lt;li>The proportion of articles that generate earnings is very low.&lt;/li>
&lt;li>English articles generate more earnings than Chinese articles, as there&amp;rsquo;s a larger English-speaking audience.&lt;/li>
&lt;/ol>
&lt;h2 id="next-steps">
&lt;a class="heading-anchor-link" href="#next-steps">Next Steps&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="next-steps"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Improve article quality and focus on key directions based on articles that have generated some earnings. Currently, aimless writing yields very low returns.&lt;/li>
&lt;li>Increase social media sharing to boost article readership. In 2024, I shared one article on Reddit and instantly got hundreds of views, which was the fastest growth I&amp;rsquo;ve seen so far.&lt;/li>
&lt;/ol>
&lt;h2 id="complaints-about-medium">
&lt;a class="heading-anchor-link" href="#complaints-about-medium">Complaints About Medium&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="complaints-about-medium"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Medium requires joining the MPP program to earn money, and joining MPP requires Medium membership first. Therefore, if monthly earnings don&amp;rsquo;t exceed $5, the membership fee is essentially wasted. Of course, if you&amp;rsquo;re also reading paid articles, it might still be worthwhile.&lt;/li>
&lt;li>Medium&amp;rsquo;s traffic seems lower than before, and you can find pessimistic voices about Medium online.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As you can see, current Medium earnings don&amp;rsquo;t cover the membership fee, so I need to keep working hard. If you have any good suggestions, feel free to share them.&lt;/p></description></item><item><title>Achieving Ebook Reading Freedom</title><link>https://en.1991421.cn/2025/02/06/ebook-reading-freedom/</link><pubDate>Thu, 06 Feb 2025 18:21:57 +0800</pubDate><guid>https://en.1991421.cn/2025/02/06/ebook-reading-freedom/</guid><description>&lt;blockquote>
&lt;p>Ebook reading really comes down to two things: a pleasant reading app and an easy way to find books. After plenty of tinkering, I finally landed on a simple, efficient setup—sharing it here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="reading-app--weread">
&lt;a class="heading-anchor-link" href="#reading-app--weread">Reading app — WeRead&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="reading-app--weread"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I’ve tried &lt;code>Kindle&lt;/code>, &lt;code>MarginNote&lt;/code>, &lt;code>Apple Books&lt;/code>, and others. After switching to WeRead (WeChat Reading), it became my favorite. A few highlights and tips:&lt;/p>
&lt;h3 id="crossplatform">
&lt;a class="heading-anchor-link" href="#crossplatform">Cross‑platform&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="crossplatform"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Download the official app directly from the iOS/Android stores.&lt;/li>
&lt;li>On macOS, grab the iPhone version from the App Store if you have an Apple silicon Mac (&lt;code>M&lt;/code> series); Intel Macs can use the web version.&lt;/li>
&lt;/ol>
&lt;h3 id="membership">
&lt;a class="heading-anchor-link" href="#membership">Membership&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="membership"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>I recommend purchasing a membership so you can read licensed titles outright. Promotional pricing hovers around &lt;code>168 CNY/year&lt;/code> (for reference).&lt;/li>
&lt;li>Claim the daily reading reward and choose the trial pass instead of book coins.
&lt;ul>
&lt;li>Book coins expire; trial passes do not.&lt;/li>
&lt;li>Trial passes can be converted into paid reading cards—essentially membership days.&lt;/li>
&lt;li>Join the reading challenges for discounted membership offers.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-02-06-184348.jpeg"
alt="https://static.1991421.cn/2025/2025-02-06-184348.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="import-ebooks">
&lt;a class="heading-anchor-link" href="#import-ebooks">Import ebooks&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="import-ebooks"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>If WeRead doesn’t have a specific title, import it yourself. Two easy approaches:&lt;/p>
&lt;ol>
&lt;li>On iPhone Files (or similar), tap an EPUB or other supported format and open it with WeRead to import.&lt;/li>
&lt;li>Visit the web app at &lt;a href="https://weread.qq.com/" target="_blank" rel="noopener">https://weread.qq.com/&lt;/a>, choose “send book to phone,” and upload the file.&lt;/li>
&lt;/ol>
&lt;h2 id="telegram-zlibrary-bot">
&lt;a class="heading-anchor-link" href="#telegram-zlibrary-bot">Telegram Z‑Library bot&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="telegram-zlibrary-bot"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When the WeRead catalog falls short, turn to the Z-Library bot on Telegram.&lt;/p>
&lt;p>Once you add the bot, search by keyword to download ebooks and then import them into WeRead.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-05-02-101044.jpeg"
alt="https://static.1991421.cn/2024/2024-05-02-101044.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Full bot setup guide: &lt;a href="https://1991421.cn/2024/05/02/5ae61aa/" target="_blank" rel="noopener">Z-Library + Telegram for ebook downloads&lt;/a>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>With WeRead plus the Z-Library bot, you can practically achieve ebook freedom. If neither source has the book, chances are there isn’t an ebook edition yet.&lt;/p></description></item><item><title>Converting MP3 and Other Formats to WeChat Silk Audio Files</title><link>https://en.1991421.cn/2025/01/24/mp3silk/</link><pubDate>Fri, 24 Jan 2025 17:44:49 +0800</pubDate><guid>https://en.1991421.cn/2025/01/24/mp3silk/</guid><description>&lt;blockquote>
&lt;p>I&amp;rsquo;ve been playing with WeChat bots in my spare time, and recently wanted to add support for sending voice files. Research shows that WeChat voice files use the Silk format, while AI voice synthesis typically provides MP3/WAV formats. So I need to solve the conversion from MP3 to Silk.&lt;/p>
&lt;/blockquote>
&lt;h2 id="silk">
&lt;a class="heading-anchor-link" href="#silk">Silk&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="silk"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>Silk is an audio compression format developed by the famous Skype company. It&amp;rsquo;s like a &amp;ldquo;sound magician&amp;rdquo; that can compress voice signals into very small sizes while maintaining high audio quality. WeChat recognized these advantages of Silk and uses it for voice message transmission.&lt;/p>
&lt;/blockquote>
&lt;h2 id="solution">
&lt;a class="heading-anchor-link" href="#solution">Solution&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="solution"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Use ffmpeg to convert to PCM (skip this step if direct PCM output is supported)&lt;/li>
&lt;li>Use pysilk to convert PCM to Silk&lt;/li>
&lt;li>Host the Silk file on a web service for WeChat sending&lt;/li>
&lt;/ul>
&lt;h2 id="mac-silk-player">
&lt;a class="heading-anchor-link" href="#mac-silk-player">Mac Silk Player&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mac-silk-player"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Recommended to use SilkPlayer&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Selection complete
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-03-09-131925.jpeg"
alt="https://static.1991421.cn/2025/2025-03-09-131925.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Choose to open
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-03-09-132011.jpeg"
alt="https://static.1991421.cn/2025/2025-03-09-132011.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Drag file to player, click play
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-03-09-132135.jpeg"
alt="https://static.1991421.cn/2025/2025-03-09-132135.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Through sending voice messages via WeChat, I learned that Silk is quite interesting. Those who are interested can research it further.&lt;/p>
&lt;h2 id="related-documentation">
&lt;a class="heading-anchor-link" href="#related-documentation">Related Documentation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documentation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.tubex.chat/en/docs/articals/2024092505" target="_blank" rel="noopener">The Secret Behind WeChat Voice: Exploring the Silk Format&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>JD Plus Membership Tips</title><link>https://en.1991421.cn/2025/01/15/jd-plus/</link><pubDate>Wed, 15 Jan 2025 21:33:50 +0800</pubDate><guid>https://en.1991421.cn/2025/01/15/jd-plus/</guid><description>&lt;blockquote>
&lt;p>As a JD Plus member for more than seven years, I’ve collected a few tips worth sharing.&lt;/p>
&lt;/blockquote>
&lt;img src="https://static.1991421.cn/2025/2025-01-15-214546.jpeg" alt="https://static.1991421.cn/2025/2025-01-15-214546.jpeg" style="zoom:50%;" />
&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>JD Plus perks change over time, so I’m only highlighting the ones I currently find most useful.&lt;/p>
&lt;h2 id="buying-a-jd-plus-membership">
&lt;a class="heading-anchor-link" href="#buying-a-jd-plus-membership">Buying a JD Plus Membership&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="buying-a-jd-plus-membership"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Purchasing directly from JD is pricey—wait for bundle promos such as Tencent Video + Plus. I usually buy through a discounted channel for about &lt;code>¥60-70/year&lt;/code>, though I’ve hit the current recharge cap.&lt;/li>
&lt;li>To catch deals, keep an eye on Telegram channels or sites like Smzdm.&lt;/li>
&lt;/ol>
&lt;h2 id="noteworthy-plus-benefits">
&lt;a class="heading-anchor-link" href="#noteworthy-plus-benefits">Noteworthy Plus Benefits&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="noteworthy-plus-benefits"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Free shipping on purchases
Great for small, urgent orders—no need to hit the free-shipping threshold.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Shopping rebates in JingDou points; remember to claim them manually. Power users might script the claim process.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://3.cn/-2aNJ8Jz" target="_blank" rel="noopener">Lifestyle service bundle&lt;/a>. The new 12-point policy is less generous, but still worthwhile.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Laundry and shoe cleaning costs &lt;code>3 points&lt;/code> and covers items like down jackets—the service quality is solid.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Free express shipping costs &lt;code>1 point&lt;/code>; in my experience it really is expedited.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Watch for limited stock on some services (car washes, etc.), so redeem early if you need them.&lt;/p>
&lt;img src="https://static.1991421.cn/2025/2025-01-15-220127.jpeg" alt="https://static.1991421.cn/2025/2025-01-15-220127.jpeg" style="zoom:50%;" />
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://3.cn/2aNLgV-e" target="_blank" rel="noopener">Free medical consultations&lt;/a>: 12 per year with real doctors. Handy when you want advice before heading to the hospital; my experiences have been positive.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;img src="https://static.1991421.cn/2025/2025-01-15-215755.jpeg" alt="https://static.1991421.cn/2025/2025-01-15-215755.jpeg" style="zoom:50%;" />
&lt;h2 id="other-perks">
&lt;a class="heading-anchor-link" href="#other-perks">Other Perks&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other-perks"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>There are additional benefits, but none impress me right now, so I’ll skip them.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Relative to the membership fee, I think it’s worth it—annual down-jacket cleaning, daily JingDou rebates, and a few shipping redemptions easily cover the cost.&lt;/li>
&lt;li>One annoyance: JD search still can’t filter for JD self-operated stores, so you have to check each store name manually.&lt;/li>
&lt;/ol></description></item><item><title>Visiting Peking University Third Hospital</title><link>https://en.1991421.cn/2025/01/06/hospital-visit-peking-university-third/</link><pubDate>Mon, 06 Jan 2025 12:11:00 +0800</pubDate><guid>https://en.1991421.cn/2025/01/06/hospital-visit-peking-university-third/</guid><description>&lt;blockquote>
&lt;p>I went to PUTH to buy finasteride and encountered various pitfalls. Here’s the full process; hope it helps.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-01-15-212559.jpeg"
alt="https://static.1991421.cn/2025/2025-01-15-212559.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="what-to-bring">
&lt;a class="heading-anchor-link" href="#what-to-bring">What to bring&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-to-bring"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Even though you can pay with the digital medical insurance card, the hospital systems go down a lot, so bring the physical card just in case.&lt;/li>
&lt;li>Appointment timing is wildly unpredictable, so take a power bank with you. If you don&amp;rsquo;t want to carry one, each floor has paid shared chargers.&lt;/li>
&lt;/ol>
&lt;h2 id="full-visit-flow">
&lt;a class="heading-anchor-link" href="#full-visit-flow">Full visit flow&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="full-visit-flow"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Make an appointment through the 114 WeChat public account.
&lt;ul>
&lt;li>Book 1–2 weeks ahead if you can; the Third Hospital&amp;rsquo;s slots disappear fast.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>On the day of your visit, use the outpatient kiosk to print your number; you can scan Alipay&amp;rsquo;s digital insurance card, your physical insurance card, or your ID card.&lt;/li>
&lt;li>After you have the number, go to the corresponding department. I went to dermatology, so I headed to the fifth floor.&lt;/li>
&lt;li>Scan the QR code to join the queue. There&amp;rsquo;s no clear confirmation on screen, so if you&amp;rsquo;re unsure, ask a staff member to check.&lt;/li>
&lt;li>Wait to be called according to the number on your ticket, and watch the display to get a sense of the current progress.&lt;/li>
&lt;li>When it&amp;rsquo;s your turn, head into the consultation room. The doctor will prescribe the medication and you&amp;rsquo;ll receive a medical record slip, which is necessary for commercial insurance reimbursement.&lt;/li>
&lt;li>Pay at any of the kiosks on each floor. When prompted for a password, the default for medical insurance accounts is six zeros. Entering the wrong password repeatedly will lock the card, and you&amp;rsquo;ll have to pay at the manual service window.&lt;/li>
&lt;li>You can also print invoice copies at the kiosks. Some machines produce faint printouts that affect reimbursement, so double-check and switch machines if needed.&lt;/li>
&lt;li>After paying, pick up your medication at the first-floor pharmacy.&lt;/li>
&lt;/ol>
&lt;h2 id="reimbursement">
&lt;a class="heading-anchor-link" href="#reimbursement">Reimbursement&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="reimbursement"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Since I needed to claim commercial insurance, I kept every receipt and submitted photos via the app.&lt;/li>
&lt;/ol>
&lt;h2 id="things-that-felt-unreasonable">
&lt;a class="heading-anchor-link" href="#things-that-felt-unreasonable">Things that felt unreasonable&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="things-that-felt-unreasonable"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>The kiosk complained about an incomplete address when I tried to print my number. Because the full address is long, it took a while to figure out that it only checks for keywords—entering something like “XX Road No. XX” works.&lt;/li>
&lt;li>You scan a QR code to queue for the department, but you&amp;rsquo;re actually called in the kiosk ticket order. If your ticket is 59, expect 58 people ahead. The only way to estimate wait time is to watch the current number being called.
&lt;ul>
&lt;li>Other hospitals such as the 306 Hospital, China-Japan Friendship Hospital, and Peking University People&amp;rsquo;s Hospital call patients based on the QR registration order and show the queue on screen.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>The kiosk suddenly asked me for a password during payment without explaining which password. After several failed attempts the machine rebooted—this happened on two different kiosks—so I had to pay at the manual window.
&lt;ul>
&lt;li>Staff later explained it&amp;rsquo;s the medical insurance payment password; the default is &lt;code>000000&lt;/code>. Entering it incorrectly multiple times locks the card, and you must visit the manual window to unlock it.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>To pick up medication on the first floor, you first scan at a pillar-mounted machine and then wait. The success prompt appears at the bottom of the giant display rather than centered, so it&amp;rsquo;s easy to miss.&lt;/li>
&lt;/ol>
&lt;p>All in all, the patient experience at PUTH is middling right now—hopefully it improves over time.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>First time at PUTH — average experience, but needs must; adapt to the process.&lt;/p></description></item><item><title>2024 Year-End Review</title><link>https://en.1991421.cn/2025/01/04/2024/</link><pubDate>Sat, 04 Jan 2025 22:25:38 +0800</pubDate><guid>https://en.1991421.cn/2025/01/04/2024/</guid><description>&lt;blockquote>
&lt;p>2024 is over, and 2025 has already begun. Looking back at 2024, it&amp;rsquo;s time for a summary.&lt;/p>
&lt;/blockquote>
&lt;h2 id="career-status">
&lt;a class="heading-anchor-link" href="#career-status">Career Status&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="career-status"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The three years from 2021 to 2024 have proven that &amp;ldquo;choosing the right path is more important than working hard.&amp;rdquo; I find myself back in a situation similar to my early years after graduation: three years spent with zero economic gain or professional promotion. In fact, income has decreased in real terms, and benefits have been steadily cut.&lt;/p>
&lt;p>The objective reason is that the company&amp;rsquo;s business is struggling. My future path there is already clear, and I&amp;rsquo;ll have to deal with it as it comes.&lt;/p>
&lt;h2 id="personal-growth--contributions">
&lt;a class="heading-anchor-link" href="#personal-growth--contributions">Personal Growth &amp;amp; Contributions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="personal-growth--contributions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Despite the poor environment, I’ve managed to maintain some personal growth.&lt;/p>
&lt;h3 id="open-source">
&lt;a class="heading-anchor-link" href="#open-source">Open Source&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="open-source"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;a href="https://github.com/alanhe421/alfred-workflows" target="_blank" rel="noopener">&lt;strong>Alfred Workflows&lt;/strong>&lt;/a>: I didn&amp;rsquo;t add many new workflows this year as the collection is quite mature. It currently features &lt;strong>56&lt;/strong> workflows with over &lt;strong>642 stars&lt;/strong>. I also built an &lt;a href="https://alfred.1991421.cn/" target="_blank" rel="noopener">official website&lt;/a> for it. This project remains my most rewarding; beyond efficiency gains, its community impact has earned me a JetBrains All Products License and a free 1Password Team License.&lt;/li>
&lt;li>&lt;a href="https://alanhe421.github.io/whisper-web/" target="_blank" rel="noopener">&lt;strong>Whisper Web&lt;/strong>&lt;/a>: A project built entirely using Cursor to convert voice recordings to text. Since iPhones don&amp;rsquo;t yet have a built-in &amp;ldquo;audio-to-Chinese-text&amp;rdquo; feature, this tool remains very useful.&lt;/li>
&lt;li>&lt;a href="https://github.com/ericclemmons/click-to-component" target="_blank" rel="noopener">&lt;strong>click-to-component&lt;/strong>&lt;/a> (PR): Added support for JetBrains IDEs to solve a personal pain point.&lt;/li>
&lt;li>&lt;a href="https://github.com/microsoft/inshellisense" target="_blank" rel="noopener">&lt;strong>inshellisense&lt;/strong>&lt;/a> (PR): Contributed a minor PR to this Microsoft project.&lt;/li>
&lt;li>&lt;a href="https://github.com/marketplace/actions/repo-discussion-count" target="_blank" rel="noopener">&lt;strong>repo-discussion-count-action&lt;/strong>&lt;/a>: Developed this GitHub Action to help track discussion counts for my Alfred workflow repository.&lt;/li>
&lt;/ul>
&lt;h3 id="blogging">
&lt;a class="heading-anchor-link" href="#blogging">Blogging&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="blogging"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>I published &lt;strong>113&lt;/strong> posts this year. Maintaining a writing habit is one of the few things I&amp;rsquo;ve stayed consistent with.&lt;/li>
&lt;/ul>
&lt;h3 id="gadgets--tools">
&lt;a class="heading-anchor-link" href="#gadgets--tools">Gadgets &amp;amp; Tools&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="gadgets--tools"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Apple Watch S10 (Macau Edition)&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Caixin Global Subscription&lt;/strong> (primarily used on iPhone).&lt;/li>
&lt;/ol>
&lt;p>For a full list of my &amp;ldquo;tools of the year,&amp;rdquo; check &lt;a href="https://en.1991421.cn/2025/01/01/c87c72e0/" target="_blank" rel="noopener">this post&lt;/a>.&lt;/p>
&lt;h2 id="travel">
&lt;a class="heading-anchor-link" href="#travel">Travel&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="travel"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Due to decreased income and ongoing mortgage payments, I didn&amp;rsquo;t travel extensively. I visited a few cities, mostly for weddings:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>March&lt;/strong>: Wuhan &amp;amp; Xianning (for a wedding).&lt;/li>
&lt;li>&lt;strong>August&lt;/strong>: Shenyang, Liaoning.&lt;/li>
&lt;li>&lt;strong>October&lt;/strong>: Henan (for a wedding).&lt;/li>
&lt;li>&lt;strong>November&lt;/strong>: Langfang, Hebei.&lt;/li>
&lt;/ol>
&lt;h2 id="housing">
&lt;a class="heading-anchor-link" href="#housing">Housing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="housing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Beijing&amp;rsquo;s housing market has seen a massive decline. There’s nothing to do but keep paying the mortgage. After two years of frugal living, the remaining balance is small, and I expect to pay it off in 2025.
Once the debt is cleared, I plan to save while also traveling more. If the current apartment feels too small, I might rent a larger place and lease this one out as a financial safety net.&lt;/p>
&lt;h2 id="finances">
&lt;a class="heading-anchor-link" href="#finances">Finances&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="finances"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Monetization&lt;/strong>: I started experimenting with blog monetization. Google AdSense currently brings in about &lt;strong>$1/month&lt;/strong>.&lt;/li>
&lt;li>&lt;strong>Medium&lt;/strong>: I&amp;rsquo;ve mirrored some articles to Medium, which also earns roughly &lt;strong>$1/month&lt;/strong>.
&lt;em>Between server/domain costs and the Medium membership fee, the blog is still technically operating at a loss.&lt;/em>&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Investments&lt;/strong>: My domestic stock portfolio saw some recovery this year but remains in the red. I&amp;rsquo;ve started exploring US stocks, but without significant spare capital, I haven&amp;rsquo;t seen substantial gains yet. Once my domestic holdings recover, I plan to shift my focus entirely to the US market.&lt;/p>
&lt;h2 id="2025-goals">
&lt;a class="heading-anchor-link" href="#2025-goals">2025 Goals&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2025-goals"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I hope to improve my work situation and break out of this cycle where effort doesn&amp;rsquo;t yield results.&lt;/p>
&lt;h2 id="final-words">
&lt;a class="heading-anchor-link" href="#final-words">Final Words&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-words"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Looking back, I&amp;rsquo;ve become the person I used to dislike: old and broke. It&amp;rsquo;s time to work hard on changing that.&lt;/p></description></item><item><title>Must-Have Tools in 2024</title><link>https://en.1991421.cn/2025/01/01/2024/</link><pubDate>Wed, 01 Jan 2025 18:04:07 +0800</pubDate><guid>https://en.1991421.cn/2025/01/01/2024/</guid><description>&lt;blockquote>
&lt;p>This year, I updated some software and hardware. There are not many items, but all are practical tools. Let&amp;rsquo;s take a look.&lt;/p>
&lt;/blockquote>
&lt;h2 id="hex-key-set">
&lt;a class="heading-anchor-link" href="#hex-key-set">Hex Key Set&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="hex-key-set"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD, price: &lt;code>45CNY&lt;/code>. I previously bought various models of Xiaomi electric screwdrivers, but I still needed hex keys. This time, I got a hex key set that includes multiple sizes, which is very practical. Combined with the Xiaomi electric screwdriver, I&amp;rsquo;m now prepared for all types of screws.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-01-01-180750.jpeg"
alt="https://static.1991421.cn/2025/2025-01-01-180750.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="solar-powered-mountain-bike-tail-light">
&lt;a class="heading-anchor-link" href="#solar-powered-mountain-bike-tail-light">Solar-Powered Mountain Bike Tail Light&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="solar-powered-mountain-bike-tail-light"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD, price: &lt;code>14CNY&lt;/code>. I found that mountain bike tail lights consume a lot of power, and changing batteries is easy to forget. I got this solar-powered tail light that can charge through solar power; It is very convenient. Also, the unit price is low, so there is no significant loss if lost.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-01-01-181030.jpeg"
alt="https://static.1991421.cn/2025/2025-01-01-181030.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="huawei-original-type-c-earphones">
&lt;a class="heading-anchor-link" href="#huawei-original-type-c-earphones">HUAWEI Original Type-C Earphones&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="huawei-original-type-c-earphones"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I purchased these from JD for &lt;code>59CNY&lt;/code>. Black looks cool, but the Apple original only comes in white, and Huawei has black, so I got these. These efficient wired earphones complement wireless ones nicely.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-01-01-181257.jpeg"
alt="https://static.1991421.cn/2025/2025-01-01-181257.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="plantronics-poly-3220-call-center-customer-service-office-headset">
&lt;a class="heading-anchor-link" href="#plantronics-poly-3220-call-center-customer-service-office-headset">Plantronics Poly 3220 Call Center Customer Service Office Headset&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="plantronics-poly-3220-call-center-customer-service-office-headset"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD, price: &lt;code>199CNY&lt;/code>. Got these headphones for my wife&amp;rsquo;s work needs.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-01-01-195117.jpeg"
alt="https://static.1991421.cn/2025/2025-01-01-195117.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="xiaomi-mi-20000mah-power-bank-with-built-in-cable">
&lt;a class="heading-anchor-link" href="#xiaomi-mi-20000mah-power-bank-with-built-in-cable">Xiaomi (MI) 20000mAh Power Bank with Built-in Cable&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xiaomi-mi-20000mah-power-bank-with-built-in-cable"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD, price: &lt;code>128CNY&lt;/code>. I previously used the MagSafe 10000mA power bank; this time, I chose a larger capacity one with a wired connection.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-01-01-194842.jpeg"
alt="https://static.1991421.cn/2025/2025-01-01-194842.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="apple-watch-s10">
&lt;a class="heading-anchor-link" href="#apple-watch-s10">Apple Watch S10&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-watch-s10"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in-store at Macau Apple Store, equivalent to &lt;code>3132CNY&lt;/code>. Compared to my previous S4, the visibly larger screen is really comfortable. As for functionality, compared to the S4, I haven&amp;rsquo;t noticed any significant changes.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-10-08-230102.jpeg"
alt="https://static.1991421.cn/2024/2024-10-08-230102.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="caixin-premium-service">
&lt;a class="heading-anchor-link" href="#caixin-premium-service">Caixin Premium &lt;code>Service&lt;/code>&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="caixin-premium-service"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Due to the current promotion, purchased from Idle Fish for 2 months, the price is &lt;code>20CNY/month&lt;/code>. Compared to WeChat official account articles and other content streams, Caixin Premium&amp;rsquo;s article quality is relatively high and worth recommending. After 2 months expire, you can only renew through official channels/recharge cards, about &lt;code>500CNY/year&lt;/code>, which is quite expensive.&lt;/p>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The above are just personal recommendations; feel free to try them if interested.&lt;/p></description></item><item><title>Elderly Parent Hukou in Beijing</title><link>https://en.1991421.cn/2024/12/28/beijing-elderly-hukou-transfer/</link><pubDate>Sat, 28 Dec 2024 00:26:19 +0800</pubDate><guid>https://en.1991421.cn/2024/12/28/beijing-elderly-hukou-transfer/</guid><description>&lt;blockquote>
&lt;p>We planned to move my mother‑in‑law’s hukou to Beijing. The procedures are numerous and the outcome is uncertain — many cases are “queued indefinitely”. Here’s the process; I’ll update if there’s progress.&lt;/p>
&lt;/blockquote>
&lt;h2 id="current-status">
&lt;a class="heading-anchor-link" href="#current-status">Current status&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-status"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>12月份时候已提交老人投靠申请，收到了&lt;code>受理决定书&lt;/code>，还在等消息，民警说会在1个月左右给消息，但目前都是在轮侯，即使资料审核过也不会立即办理入户，具体要等上面给消息。&lt;/li>
&lt;li>2025年1月底收到派出所电话，去签字-不予许可决定书。&lt;/li>
&lt;/ol>
&lt;p>Not successful yet, but at least we’re in the queue. Documents prepared below:&lt;/p>
&lt;h2 id="requirements-and-documents">
&lt;a class="heading-anchor-link" href="#requirements-and-documents">Requirements and documents&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="requirements-and-documents"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>在开始准备时，建议是跑一趟所在地区派出所，取一下最新的要求文件，上面会说明白需要准备的资料，每个时间段要求的材料会有所不同。比如今年上半年和下半年的就有所不同。&lt;/p>
&lt;p>What we prepared:&lt;/p>
&lt;ol>
&lt;li>老人的户口本/身份证/照片/退休证明/镇政府出具的查档证明&lt;/li>
&lt;li>北京这边的户口本/结婚证/身份证/公司出具的查档证明&lt;/li>
&lt;/ol>
&lt;p>Note: date on the “record check” letter must be within the same calendar year as submission.&lt;/p>
&lt;h3 id="use-12345-and-similar-channels">
&lt;a class="heading-anchor-link" href="#use-12345-and-similar-channels">Use 12345 and similar channels&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="use-12345-and-similar-channels"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The township initially refused to issue a letter; community-stamped letters weren’t accepted by the Beijing PSB. Calling 12345 applied pressure; the township asked for a formal letter from the Beijing PSB. After explaining, the PSB agreed to provide a paper letter, and the township then relented and issued the document without needing that letter.&lt;/p>
&lt;p>最终在凑齐所有手续文件后，带着家人，直接去派出所让民警预审材料了，当民警告诉OK了，就可以正常提交了。但提交录入系统必须是工作日。录入后，会给受理决定书，签字后就可以回家等消息了。&lt;/p>
&lt;h2 id="acceptance-notice">
&lt;a class="heading-anchor-link" href="#acceptance-notice">Acceptance notice&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="acceptance-notice"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>决定书编号的后四位是排名&lt;code>听说是这样&lt;/code>。&lt;/li>
&lt;li>目前的政策情况决定，受理决定书后，会收到不予通过即代表着轮后，遥遥无期。&lt;/li>
&lt;/ol>
&lt;h2 id="beijing-2024-hukou-data">
&lt;a class="heading-anchor-link" href="#beijing-2024-hukou-data">Beijing 2024 hukou data&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="beijing-2024-hukou-data"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>这里分享一个微信群看到的落户数据，只能说落户真难。&lt;/p>
&lt;blockquote>
&lt;p>欢迎各位，北京最常见的积分落户，计算方式如下图：
2024年北京积分落户共有10万人申请，6002人成功，录取5.9%。普遍集中在42岁左右，上岸分数线114分。
在职提升学历的占47%；74%的人具有硕士以上学历，20%的人具有博士学历；年收入在70万以下的仅21%。99%的人都在郊区有房，其中93%的人郊区有房6年以上，只有2人郊区无房。
投靠层面，基本都改轮候了：
夫妻需要老家+北京无业2年，45岁结婚满10年；子女随迁，要求未满18岁；父母要求双退休，外省无子女，没听说轮候成功的
学历落户：
目前留服只给中直单位央企指标，不给北京市指标了，北京市统一走人社ju渠道。
应届生对年纪有严格限制，研究生在27周岁以内，博士在35周岁以内；
博后本人的落户不明朗，配偶要结婚21个月了。&lt;/p>
&lt;/blockquote>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>It’s hard to obtain hukou, especially for the elderly; spousal hukou is also difficult. New graduates hoping to stay in Beijing should seize any window of opportunity.&lt;/p></description></item><item><title>NAS with Alist Integration to Solve Quark Cloud Drive Viewing Experience Issues</title><link>https://en.1991421.cn/2024/12/25/nasalist/</link><pubDate>Wed, 25 Dec 2024 22:45:11 +0800</pubDate><guid>https://en.1991421.cn/2024/12/25/nasalist/</guid><description>&lt;blockquote>
&lt;p>Quark Cloud Drive cannot be directly integrated into Infuse for viewing. To make movie watching more convenient, here we combine NAS+Alist to solve cloud drive experience issues.&lt;/p>
&lt;/blockquote>
&lt;h2 id="alist">
&lt;a class="heading-anchor-link" href="#alist">Alist&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="alist"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Add Quark Cloud Drive under alist.&lt;/li>
&lt;li>alist service supports providing WebDAV externally, enabled by default. The address is &lt;code>http[s]://domain:port/dav/&lt;/code>, with the same username and password as the web interface. For example, mine is &lt;code>https://alist.1991421.cn/dav&lt;/code>.&lt;/li>
&lt;/ol>
&lt;h2 id="nas-cloudsync">
&lt;a class="heading-anchor-link" href="#nas-cloudsync">NAS-CloudSync&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="nas-cloudsync"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Add WebDav service, select the folder to sync. After the task starts, cloud drive resources will gradually download to the NAS.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-12-25-225627.jpeg"
alt="https://static.1991421.cn/2024/2024-12-25-225627.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="infusevideo">
&lt;a class="heading-anchor-link" href="#infusevideo">Infuse/Video&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="infusevideo"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After NAS downloads the resources, there are many viewing options. Add NAS WebDAV service in Infuse or directly use NAS Video for viewing. Since cloud drive resources have been synced and downloaded to NAS, as long as NAS speed is fine.&lt;/p>
&lt;p>If at home, recommended to add NAS via local network form; if on public network, add domain name/IP.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Following the above method, whether it&amp;rsquo;s Quark/Aliyun Cloud Drive/Baidu, all can be solved with this solution. But the drawback is that key resources are not timely, after all, NAS download synchronization is needed.&lt;/p>
&lt;h2 id="related-documentation">
&lt;a class="heading-anchor-link" href="#related-documentation">Related Documentation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documentation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://alist.nn.ci/zh/guide/webdav.html" target="_blank" rel="noopener">https://alist.nn.ci/zh/guide/webdav.html&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Updating GLIBC on CentOS 7</title><link>https://en.1991421.cn/2024/12/16/centos7glibc/</link><pubDate>Mon, 16 Dec 2024 14:00:19 +0800</pubDate><guid>https://en.1991421.cn/2024/12/16/centos7glibc/</guid><description>&lt;blockquote>
&lt;p>When executing npm commands on the target server, I encountered the error &amp;ldquo;node: /lib64/libm.so.6: version `GLIBC_2.27&amp;rsquo; not found (required by node)&amp;rdquo;. Here I&amp;rsquo;ll mark down the repair process.&lt;/p>
&lt;/blockquote>
&lt;h2 id="commands">
&lt;a class="heading-anchor-link" href="#commands">Commands&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="commands"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-gdscript3" data-lang="gdscript3">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Check current version&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ldd&lt;/span> &lt;span class="o">--&lt;/span>&lt;span class="n">version&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Download&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wget&lt;/span> &lt;span class="n">http&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="n">ftp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gnu&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">org&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="n">gnu&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="n">libc&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="n">glibc&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mf">2.25&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">tar&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gz&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Bundle Size Issues Caused by Misusing Lodash</title><link>https://en.1991421.cn/2024/12/11/lodash/</link><pubDate>Wed, 11 Dec 2024 15:58:40 +0800</pubDate><guid>https://en.1991421.cn/2024/12/11/lodash/</guid><description>&lt;blockquote>
&lt;p>I spotted problematic lodash imports in a real project and wanted to document the fix.&lt;/p>
&lt;/blockquote>
&lt;h2 id="the-problem">
&lt;a class="heading-anchor-link" href="#the-problem">The Problem&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-problem"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The project depended on the CommonJS build of lodash in &lt;code>package.json&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">_&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;lodash&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">cloneDeep&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;lodash&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Regardless of the bundler, both patterns pull the entire library.&lt;/p>
&lt;h2 id="the-quick-fix">
&lt;a class="heading-anchor-link" href="#the-quick-fix">The Quick Fix&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-quick-fix"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">cloneDeep&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;lodash/cloneDeep&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This only brings in &lt;code>cloneDeep&lt;/code>. The downsides:&lt;/p>
&lt;ol>
&lt;li>Multiple functions mean multiple import lines.&lt;/li>
&lt;li>Those per-method modules are still CommonJS files that re-require other helpers, so extra code sneaks in anyway.&lt;/li>
&lt;/ol>
&lt;h2 id="the-better-option">
&lt;a class="heading-anchor-link" href="#the-better-option">The Better Option&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-better-option"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Lodash ships an &lt;a href="https://www.npmjs.com/package/lodash-es" target="_blank" rel="noopener">ES module build&lt;/a>. You can swap dependencies to &lt;code>lodash-es&lt;/code>, or alias it without touching call sites:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;lodash&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;npm:lodash-es@^4.17.21&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then import like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">cloneDeep&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;lodash-es&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Even with the ES module, avoid &lt;code>import _ from 'lodash-es'&lt;/code>; that still drags in the whole bundle.&lt;/p>
&lt;h2 id="size-difference-after-the-change">
&lt;a class="heading-anchor-link" href="#size-difference-after-the-change">Size Difference After the Change&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="size-difference-after-the-change"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In testing, the optimized imports trimmed roughly 100 KB.&lt;/p>
&lt;h3 id="before">
&lt;a class="heading-anchor-link" href="#before">Before&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="before"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-12-11-160835.jpeg"
alt="https://static.1991421.cn/2024/2024-12-11-160835.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="after">
&lt;a class="heading-anchor-link" href="#after">After&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="after"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-12-11-161011.jpeg"
alt="https://static.1991421.cn/2024/2024-12-11-161011.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The root of the size issue is that CommonJS modules are bundled wholesale, whereas ES modules let your tooling tree-shake away the unused code.&lt;/p></description></item><item><title>AntV X6 Diagramming: Step-by-Step Guide</title><link>https://en.1991421.cn/2024/11/20/antv-x6/</link><pubDate>Wed, 20 Nov 2024 18:34:08 +0800</pubDate><guid>https://en.1991421.cn/2024/11/20/antv-x6/</guid><description>&lt;blockquote>
&lt;p>Recently, a work requirement needed to draw DAG graphs with interactive operations. After research, I decided to use AntV X6 as the solution. After using it in practice, here&amp;rsquo;s a summary of common issues.&lt;/p>
&lt;/blockquote>
&lt;h2 id="how-to-choose-between-x6-g6-and-others">
&lt;a class="heading-anchor-link" href="#how-to-choose-between-x6-g6-and-others">How to choose between X6, G6, and others&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-to-choose-between-x6-g6-and-others"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>There are many visualization graph libraries under AntV, so how do you choose? In fact, each library has a different positioning, so use what fits your needs. Here&amp;rsquo;s the official introduction to each library.&lt;/p>
&lt;h2 id="antv-plugins">
&lt;a class="heading-anchor-link" href="#antv-plugins">AntV plugins&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="antv-plugins"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As you can see, AntV provides many plugins that can be loaded as needed. For example, to implement a component that deletes selected nodes with the backspace key, you need the selection and keyboard plugins.&lt;/p>
&lt;p>For a specific list of plugins, see here: &lt;a href="https://github.com/antvis/X6/tree/master/packages" target="_blank" rel="noopener">https://github.com/antvis/X6/tree/master/packages&lt;/a>&lt;/p>
&lt;h2 id="custom-node-styles">
&lt;a class="heading-anchor-link" href="#custom-node-styles">Custom node styles&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="custom-node-styles"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h2 id="automatic-layout">
&lt;a class="heading-anchor-link" href="#automatic-layout">Automatic layout&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="automatic-layout"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Install the dependency package &lt;a href="https://www.npmjs.com/package/dagre" target="_blank" rel="noopener">&lt;code>dagre&lt;/code>&lt;/a>&lt;/li>
&lt;li>During initial rendering, just call the &lt;code>layout(graph)&lt;/code> method.&lt;/li>
&lt;/ul>
&lt;p>The implementation code for layout is as follows, for reference only.&lt;/p>
&lt;p>&lt;a href="https://gist.githubusercontent.com/alanhe421/1e2942d8e7134a53f1e54d4802c3e437/raw/f0b06508525f12874d36831935e8fb04dcb39a4c/antv-x6-layout.ts" target="_blank" rel="noopener">https://gist.githubusercontent.com/alanhe421/1e2942d8e7134a53f1e54d4802c3e437/raw/f0b06508525f12874d36831935e8fb04dcb39a4c/antv-x6-layout.ts&lt;/a>&lt;/p>
&lt;h2 id="3d25d-support">
&lt;a class="heading-anchor-link" href="#3d25d-support">3D/2.5D support?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="3d25d-support"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The official library doesn&amp;rsquo;t provide a solution for this; you currently need to solve it yourself.&lt;/p>
&lt;h2 id="20-plan">
&lt;a class="heading-anchor-link" href="#20-plan">2.0 Plan&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="20-plan"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>👉 &lt;a href="https://www.yuque.com/antv/x6/sk3zdn_nsgg4p" target="_blank" rel="noopener">https://www.yuque.com/antv/x6/sk3zdn_nsgg4p&lt;/a>&lt;/p>
&lt;h2 id="related-documentation">
&lt;a class="heading-anchor-link" href="#related-documentation">Related Documentation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documentation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://antv.antgroup.com/" target="_blank" rel="noopener">https://antv.antgroup.com/&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>How to Use Synology Photos (Step-by-Step Guide)</title><link>https://en.1991421.cn/2024/11/14/synology-photos/</link><pubDate>Thu, 14 Nov 2024 22:24:30 +0800</pubDate><guid>https://en.1991421.cn/2024/11/14/synology-photos/</guid><description>&lt;blockquote>
&lt;p>I wanted to browse family photos on Apple TV, so I revisited Synology Photos. Here’s my setup.&lt;/p>
&lt;/blockquote>
&lt;h2 id="install--sign-in">
&lt;a class="heading-anchor-link" href="#install--sign-in">Install &amp;amp; Sign In&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="install--sign-in"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-11-14-223151.jpeg"
alt="https://static.1991421.cn/2024/2024-11-14-223151.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ol>
&lt;li>Log into DSM → &lt;strong>Package Center&lt;/strong> → install &lt;strong>Synology Photos&lt;/strong> (not the deprecated DS Photo).&lt;/li>
&lt;li>On iPhone/Apple TV, install &lt;strong>Synology Photos&lt;/strong> from the App Store and sign in.&lt;/li>
&lt;/ol>
&lt;h2 id="add-photos">
&lt;a class="heading-anchor-link" href="#add-photos">Add Photos&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="add-photos"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Upload via the DSM web interface.&lt;/li>
&lt;li>On iOS, enable uploads or automatic backup directly in the mobile app.&lt;/li>
&lt;/ul>
&lt;h2 id="combine-with-cloud-sync-eg-baidu-cloud">
&lt;a class="heading-anchor-link" href="#combine-with-cloud-sync-eg-baidu-cloud">Combine with Cloud Sync (e.g., Baidu Cloud)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="combine-with-cloud-sync-eg-baidu-cloud"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Cloud Sync often creates folders outside the default Photos path (&lt;code>/homes/&amp;lt;user&amp;gt;/Photos&lt;/code>), so synced images won’t show up. Two options:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Copy files manually into the Photos folder (not recommended).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Bind the synced folder into Photos:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">mount --bind /volume1/Download/Cloud-Disk/PersonalPhotos /var/services/homes/&amp;lt;user&amp;gt;/Photos/PersonalPhotos
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>After binding, rebuild the Synology Photos index. Run the mount via SSH or create a scheduled script in DSM.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="remote-access">
&lt;a class="heading-anchor-link" href="#remote-access">Remote Access&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="remote-access"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>QuickConnect is the easiest option.&lt;/li>
&lt;li>For custom domains, you’ll need a public IP + DDNS (or a static IP).&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>With this in place, Synology Photos becomes genuinely useful for multi-device photo viewing.&lt;/p></description></item><item><title>Recommended YouTube Channels (for Chinese-Speaking Digital Nomads)</title><link>https://en.1991421.cn/2024/11/11/youtube-for/</link><pubDate>Mon, 11 Nov 2024 22:40:10 +0800</pubDate><guid>https://en.1991421.cn/2024/11/11/youtube-for/</guid><description>&lt;blockquote>
&lt;p>I&amp;rsquo;ve been scrolling YouTube for about ten years and watch it regularly while barely using domestic short‑video platforms like Bilibili.&lt;/p>
&lt;p>To navigate YouTube better, I&amp;rsquo;ve compiled a list of channels I watch and find high quality.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-11-13-122923.jpeg"
alt="https://static.1991421.cn/2024/2024-11-13-122923.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="channel-list">
&lt;a class="heading-anchor-link" href="#channel-list">Channel List&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="channel-list"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="technology-and-digital">
&lt;a class="heading-anchor-link" href="#technology-and-digital">Technology and Digital&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="technology-and-digital"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/@Apple" target="_blank" rel="noopener">Apple&lt;/a>: Apple&amp;rsquo;s official channel featuring product launch events, ads, and tutorials.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@GitHub" target="_blank" rel="noopener">GitHub&lt;/a>: GitHub&amp;rsquo;s official channel for developer tools, tutorials, and community events.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@MicrosoftDeveloper" target="_blank" rel="noopener">Microsoft Developer&lt;/a>: Microsoft&amp;rsquo;s developer channel, providing tools and technology sharing.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@lyi" target="_blank" rel="noopener">Linyi LYi&lt;/a>: Tech product reviews and user experiences.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@%E5%85%88%E7%9C%8B%E8%AF%84%E6%B5%8B" target="_blank" rel="noopener">Review First&lt;/a>: Product reviews and data to help purchasing decisions.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@bestpartners" target="_blank" rel="noopener">Best Partners TV&lt;/a>: Lifestyle and entertainment content.&lt;/li>
&lt;/ul>
&lt;h3 id="history-and-culture">
&lt;a class="heading-anchor-link" href="#history-and-culture">History and Culture&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="history-and-culture"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/@ChinaHistoryTalks" target="_blank" rel="noopener">CCTV Lecture Room&lt;/a>: Historical and cultural program, storytelling Chinese history.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@%E5%8F%B2%E6%B5%B7%E6%8B%BE%E8%B4%9D%E4%BA%BA" target="_blank" rel="noopener">History Shell Collector&lt;/a>: Self‑media exploring human nature through historical events.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@%E7%9B%B4%E7%94%B7%E6%96%87%E5%8F%B2%E8%AF%BE" target="_blank" rel="noopener">Straight Guy History Class&lt;/a>: Uses comics to teach history.&lt;/li>
&lt;/ul>
&lt;h3 id="entertainment-and-variety">
&lt;a class="heading-anchor-link" href="#entertainment-and-variety">Entertainment and Variety&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="entertainment-and-variety"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/@1818%E9%BB%84%E9%87%91%E7%9C%BC" target="_blank" rel="noopener">1818 Golden Eye&lt;/a>: Down‑to‑earth news program.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@MangoTV-Music" target="_blank" rel="noopener">MangoTV Music Channel&lt;/a>: Music programs and MVs.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@mediastorm6801" target="_blank" rel="noopener">Mediastorm&lt;/a>: Film/TV teaching, gear reviews, shorts, and commercial content.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@shayushuo" target="_blank" rel="noopener">Sharky Movie Talk&lt;/a>: Classic movies and life stories.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@1001RIO" target="_blank" rel="noopener">Rio Eats&lt;/a>: Food exploration and recommendations.&lt;/li>
&lt;/ul>
&lt;h3 id="crime">
&lt;a class="heading-anchor-link" href="#crime">Crime&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="crime"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/@zhengjixiang" target="_blank" rel="noopener">Zheng Jixiang&lt;/a>: Cases from ancient to modern times through simple sketches.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@xdiaocha" target="_blank" rel="noopener">X Investigation&lt;/a>: Stories of detectives, reasoning, curious people, and mysteries.&lt;/li>
&lt;/ul>
&lt;h3 id="travel-and-food">
&lt;a class="heading-anchor-link" href="#travel-and-food">Travel and Food&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="travel-and-food"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/@Shijingji" target="_blank" rel="noopener">Shijingji&lt;/a>: Street food across the country.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@MaiZong" target="_blank" rel="noopener">MaiZong Eats&lt;/a>: Food exploration and reviews.&lt;/li>
&lt;/ul>
&lt;h3 id="health-and-fitness">
&lt;a class="heading-anchor-link" href="#health-and-fitness">Health and Fitness&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="health-and-fitness"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/@funsportgym" target="_blank" rel="noopener">FunSport Fitness&lt;/a>: Fitness and exercise tutorials.&lt;/li>
&lt;/ul>
&lt;h3 id="games-and-entertainment">
&lt;a class="heading-anchor-link" href="#games-and-entertainment">Games and Entertainment&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="games-and-entertainment"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/@IGN" target="_blank" rel="noopener">IGN&lt;/a>: Game reviews, news, walkthroughs.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@NBAhighlightnba" target="_blank" rel="noopener">Highlight NBA&lt;/a>: NBA highlights and news.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@testvcn" target="_blank" rel="noopener">TESTV&lt;/a>: Humorous reviews of tech products and daily items.&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@ToyFilms" target="_blank" rel="noopener">ToyFilms SnowboardMovie&lt;/a>: Skiing videos and related content.&lt;/li>
&lt;/ul>
&lt;h3 id="education-and-learning">
&lt;a class="heading-anchor-link" href="#education-and-learning">Education and Learning&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="education-and-learning"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/@GPINTALK" target="_blank" rel="noopener">GPINTALK&lt;/a>: Aviation knowledge and industry information.&lt;/li>
&lt;/ul></description></item><item><title>First Apartment Hardware List</title><link>https://en.1991421.cn/2024/11/03/first-house-hardware-list/</link><pubDate>Sun, 03 Nov 2024 22:28:36 +0800</pubDate><guid>https://en.1991421.cn/2024/11/03/first-house-hardware-list/</guid><description>&lt;blockquote>
&lt;p>I&amp;rsquo;ve lived in my first apartment for 1.5 years now. Overall, I think the hardware choices were pretty good. Here&amp;rsquo;s a record of them.&lt;/p>
&lt;/blockquote>
&lt;p>The apartment itself was chosen with Beewo Decoration, so the foundation is decent. On this basis, I supplemented with hardware.&lt;/p>
&lt;h2 id="tv">
&lt;a class="heading-anchor-link" href="#tv">TV&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tv"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Limited by apartment size and budget constraints, I currently chose Philips. When I move to a bigger place, I still plan to go with Sony. But for now, Philips is sufficient, in the 2K-3K price range.&lt;/p>
&lt;h2 id="air-conditioner">
&lt;a class="heading-anchor-link" href="#air-conditioner">Air Conditioner&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="air-conditioner"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Gree&lt;/p>
&lt;h2 id="refrigerator">
&lt;a class="heading-anchor-link" href="#refrigerator">Refrigerator&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="refrigerator"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Panasonic. Limited by apartment size, I bought a single-door model, but it&amp;rsquo;s quite good. The space is relatively large and currently meets the needs of a two-person household.&lt;/p>
&lt;h2 id="washing-machine">
&lt;a class="heading-anchor-link" href="#washing-machine">Washing Machine&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="washing-machine"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Little Swan. Cheap and works well. It also has mini-program networking support, but I find the experience too cumbersome. Currently used to direct operation.&lt;/p>
&lt;h2 id="water-heater">
&lt;a class="heading-anchor-link" href="#water-heater">Water Heater&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="water-heater"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Haier&lt;/p>
&lt;h2 id="bed-wardrobe">
&lt;a class="heading-anchor-link" href="#bed-wardrobe">Bed, Wardrobe&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bed-wardrobe"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Kuka Home. Good quality.&lt;/p>
&lt;h2 id="computer-desk">
&lt;a class="heading-anchor-link" href="#computer-desk">Computer Desk&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="computer-desk"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Loctek. 2K cost, very good.&lt;/p>
&lt;h2 id="tv-cabinet">
&lt;a class="heading-anchor-link" href="#tv-cabinet">TV Cabinet&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tv-cabinet"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>QuanU Furniture. Hundred yuan cost, very good, extremely cost-effective.&lt;/p>
&lt;h2 id="outlets--switches">
&lt;a class="heading-anchor-link" href="#outlets--switches">Outlets &amp;amp; Switches&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="outlets--switches"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Bull. Quality and safe, more reassuring.&lt;/p>
&lt;h2 id="toilet">
&lt;a class="heading-anchor-link" href="#toilet">Toilet&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="toilet"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Arrow. First-class energy efficiency. In 1.5 years of use, no problems have occurred.&lt;/p>
&lt;h2 id="desk-lamp">
&lt;a class="heading-anchor-link" href="#desk-lamp">Desk Lamp&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="desk-lamp"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Xiaomi&lt;/p>
&lt;h2 id="digital-clockthermometer">
&lt;a class="heading-anchor-link" href="#digital-clockthermometer">Digital Clock/Thermometer&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="digital-clockthermometer"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Xiaomi&lt;/p></description></item><item><title>Personal Hardware List</title><link>https://en.1991421.cn/2024/10/22/my-hardware-list/</link><pubDate>Tue, 22 Oct 2024 09:46:18 +0800</pubDate><guid>https://en.1991421.cn/2024/10/22/my-hardware-list/</guid><description>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-10-24-232203.jpeg"
alt="https://static.1991421.cn/2024/2024-10-24-232203.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;code>Continuously updated&lt;/code>&lt;/p>
&lt;h2 id="macbook-pro-2024-14inch-">
&lt;a class="heading-anchor-link" href="#macbook-pro-2024-14inch-">MacBook Pro 2024 14‑inch 💻&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="macbook-pro-2024-14inch-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Currently using a company‑issued M3 Pro, 12‑core/36 GB RAM/1 TB SSD — plenty. I’ve grown used to 14 inches; it strikes a nice balance between portability and performance.&lt;/p>
&lt;h2 id="mac-mini-2024">
&lt;a class="heading-anchor-link" href="#mac-mini-2024">Mac mini 2024&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mac-mini-2024"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased early 2025: M4 with 10 cores/24 GB RAM/512 GB SSD. Compact and sufficient for home use.&lt;/p>
&lt;h2 id="macbook-air-2025-13inch-">
&lt;a class="heading-anchor-link" href="#macbook-air-2025-13inch-">MacBook Air 2025 13‑inch 💻&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="macbook-air-2025-13inch-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased early 2025: M4 with 10 cores/16 GB RAM/256 GB SSD. Intended for non‑work scenarios at home or on the go — a personal backup beyond the limitations of a company machine.&lt;/p>
&lt;h2 id="airpods-3-">
&lt;a class="heading-anchor-link" href="#airpods-3-">AirPods 3 🎧&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="airpods-3-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>AirPods loyalist from Gen 1 through Gen 3 — excellent earbuds.&lt;/p>
&lt;h2 id="apple-watch-s10-">
&lt;a class="heading-anchor-link" href="#apple-watch-s10-">Apple Watch S10 ⌚️&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-watch-s10-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Long‑time Apple Watch user. Recently retired a Series 4 for an S10 for the larger screen — very happy. Next up, probably Ultra.&lt;/p>
&lt;h2 id="airtag">
&lt;a class="heading-anchor-link" href="#airtag">AirTag&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="airtag"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>On my keys — decorative and, more importantly, helpful with Find My. Love it. Battery life is solid; 1.5 years in without a swap.&lt;/p>
&lt;h2 id="apple-tv-5">
&lt;a class="heading-anchor-link" href="#apple-tv-5">Apple TV 5&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-tv-5"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Using the 5th gen — sufficient. Mostly Infuse + YouTube + Surge for shows. Beats domestic TV boxes by a mile.&lt;/p>
&lt;h2 id="filco-87-wireless-s2-">
&lt;a class="heading-anchor-link" href="#filco-87-wireless-s2-">Filco 87 Wireless (S2) ⌨️&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="filco-87-wireless-s2-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I like 87‑key layouts. Great build quality; exaggerating a bit, but this could last a lifetime.&lt;/p>
&lt;h2 id="logitech-m720-">
&lt;a class="heading-anchor-link" href="#logitech-m720-">Logitech M720 🖱️&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="logitech-m720-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Supports multi‑device switching and Bluetooth. Around ¥100 — very good value.&lt;/p>
&lt;h2 id="anker-magsafe-power-bank-">
&lt;a class="heading-anchor-link" href="#anker-magsafe-power-bank-">Anker MagSafe Power Bank 🔋&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="anker-magsafe-power-bank-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Anker quality is solid. I bought two 10,000 mAh units. 7.5 W charging is slow, but convenient — fine for on‑the‑go emergencies.&lt;/p>
&lt;h2 id="thermos-insulated-tumbler">
&lt;a class="heading-anchor-link" href="#thermos-insulated-tumbler">Thermos Insulated Tumbler&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="thermos-insulated-tumbler"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Vacuum insulated tumbler for year‑round use. Tiger is also good; either brand works.&lt;/p>
&lt;h2 id="loctek-electric-standing-desk">
&lt;a class="heading-anchor-link" href="#loctek-electric-standing-desk">Loctek Electric Standing Desk&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="loctek-electric-standing-desk"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Multiple memory presets. Standing at home is great. High value for the price.&lt;/p>
&lt;h2 id="muji-beanbag-sofa">
&lt;a class="heading-anchor-link" href="#muji-beanbag-sofa">MUJI Beanbag Sofa&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="muji-beanbag-sofa"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The most comfortable beanbag I’ve tried so far.&lt;/p></description></item><item><title>Getting the Apple Watch S10</title><link>https://en.1991421.cn/2024/10/08/apple-watch-s10/</link><pubDate>Tue, 08 Oct 2024 22:44:01 +0800</pubDate><guid>https://en.1991421.cn/2024/10/08/apple-watch-s10/</guid><description>&lt;blockquote>
&lt;p>I got the Apple Watch S4 in November 2018 and have used it for almost six years. The battery health has dropped to 77%. Considering that the latest Watch OS11 no longer supports the S4 and has been used for a long time, I decided to get the S10.&lt;/p>
&lt;p>After using the S10 for a few days, I&amp;rsquo;ve compiled the pros and cons for your reference.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-10-08-230102.jpeg"
alt="https://static.1991421.cn/2024/2024-10-08-230102.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="purchased-version">
&lt;a class="heading-anchor-link" href="#purchased-version">Purchased Version&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchased-version"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>First, let me explain the version I bought.&lt;/p>
&lt;ul>
&lt;li>My S4 was the &lt;code>GPS 44mm&lt;/code> version; this time, I chose the &lt;code>GPS 46mm&lt;/code> version (the new version only comes in 42mm and 46mm).&lt;/li>
&lt;li>Since the mainland China doesn&amp;rsquo;t support fast charging, I opted for another version. I chose the Macao version, priced at &lt;code>3499MOP&lt;/code>, equivalent to &lt;code>3132CNY&lt;/code>.&lt;/li>
&lt;li>As for the color, I went with glossy black. Regarding paint chipping, I&amp;rsquo;ll have to see after using it for a while.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>The reason I didn’t buy the Ultra version is purely due to budget constraints.&lt;/strong>&lt;/p>
&lt;h2 id="s10-vs-s4">
&lt;a class="heading-anchor-link" href="#s10-vs-s4">S10 vs. S4&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="s10-vs-s4"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>This compares the S10 and S4, so the differences are more apparent.&lt;/p>
&lt;/blockquote>
&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Visibly &lt;code>larger screen&lt;/code> and &lt;code>thinner&lt;/code> design.&lt;/li>
&lt;li>&lt;code>Fast charging&lt;/code>: charging from 0% to 80% only takes 30 minutes. The S4 does not have fast charging.&lt;/li>
&lt;li>The screen is always on, so you can see the watch information without raising your wrist. The screen is also brighter during regular display.&lt;/li>
&lt;li>The charging cable is now woven, which feels and looks higher quality.&lt;/li>
&lt;li>The double-tap gesture is convenient.&lt;/li>
&lt;/ul>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>There aren&amp;rsquo;t any significant cons compared to the S4. Just keep in mind that the mainland China version lacks fast charging.&lt;/p>
&lt;p>Of course, the Watch itself still has some drawbacks.&lt;/p>
&lt;ul>
&lt;li>Battery life still requires daily charging and cannot last two full days. It would be amazing if it could match Garmin&amp;rsquo;s battery life.&lt;/li>
&lt;/ul>
&lt;h2 id="at-the-end">
&lt;a class="heading-anchor-link" href="#at-the-end">At the end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="at-the-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In short, the S10 is great, and I recommend that new users and old users with devices like the S4 try it.&lt;/p>
&lt;h2 id="related-links">
&lt;a class="heading-anchor-link" href="#related-links">Related Links&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-links"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.apple.com/hk/watch/compare/?modelList=watch-series-4,watch-series-10" target="_blank" rel="noopener">https://www.apple.com/hk/watch/compare/?modelList=watch-series-4,watch-series-10&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Toutiao Search SEO</title><link>https://en.1991421.cn/2024/09/20/toutiao-search-seo/</link><pubDate>Fri, 20 Sep 2024 10:26:30 +0800</pubDate><guid>https://en.1991421.cn/2024/09/20/toutiao-search-seo/</guid><description>&lt;blockquote>
&lt;p>I already submitted the blog to Google, Baidu, and Bing, but never to &lt;a href="https://www.toutiao.com/" target="_blank" rel="noopener">Toutiao Search&lt;/a>. I added it today—here’s the process.&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>Add the domain (subdomains aren’t grouped—you must add each host separately).&lt;/li>
&lt;li>Verify ownership via HTML file or meta tag; I chose the meta tag.&lt;/li>
&lt;li>Submit the sitemap.&lt;/li>
&lt;li>Enable automatic indexing by injecting their JS snippet into the site.&lt;/li>
&lt;/ol>
&lt;p>Console: &lt;a href="https://zhanzhang.toutiao.com/" target="_blank" rel="noopener">https://zhanzhang.toutiao.com/&lt;/a>&lt;/p></description></item><item><title>How to Use Draw.io (Step-by-Step Guide)</title><link>https://en.1991421.cn/2024/08/25/draw-io/</link><pubDate>Sun, 25 Aug 2024 20:42:44 +0800</pubDate><guid>https://en.1991421.cn/2024/08/25/draw-io/</guid><description>&lt;blockquote>
&lt;p>Technical reviews are required for functions that take more than three days to develop, so drawing skills are essential.&lt;/p>
&lt;p>My company encourages the use of draw.io for drawing, and the more I use it, the more amazing I find this tool. So, regarding its usage, here’s a basic explanation for marking.&lt;/p>
&lt;/blockquote>
&lt;img src="https://www.drawio.com/assets/img/blog/connector-flow-animation.svg" alt="https://www.drawio.com/assets/img/blog/connector-flow-animation.svg" style="zoom:50%;" />
&lt;h2 id="platform">
&lt;a class="heading-anchor-link" href="#platform">Platform&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="platform"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Draw.io is free and cross-platform.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://app.diagrams.net/" target="_blank" rel="noopener">Web&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://github.com/jgraph/drawio-desktop/releases" target="_blank" rel="noopener">App&lt;/a>&lt;/p>
&lt;p>It uses Electron, so it supports various OS.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="open-source">
&lt;a class="heading-anchor-link" href="#open-source">Open Source?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="open-source"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Draw.io is an open-source project that can be commercialized and redeveloped. Draw.io uses the Apache2 license, which is relatively permissive.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Internally, my company uses Draw.io integrated with Confluence, making creating drawings directly in Wiki convenient.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Project link, &lt;a href="https://github.com/jgraph/drawio" target="_blank" rel="noopener">click here&lt;/a>&lt;/p>
&lt;h2 id="usage">
&lt;a class="heading-anchor-link" href="#usage">Usage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For specific usage, it is recommended to watch the official video tutorials. Here are some tips:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Pay attention to the use of hotkeys.&lt;/p>
&lt;p>Draw.io has a set of intuitive hotkeys, and it is recommended that you practice them deliberately. This can improve drawing efficiency.&lt;/p>
&lt;p>&lt;a href="https://drawio-app.com/tutorials/shortcuts/" target="_blank" rel="noopener">https://drawio-app.com/tutorials/shortcuts/&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Draw.io supports animated connectors, just like the image at the beginning of the article, which looks fantastic.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>It supports cross-line settings, so even intersecting lines can remain clear.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Make good use of the search function on the left.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>When exporting, if you want to keep the connector animation, you can choose SVG and then convert it to GIF.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Use templates when creating diagrams. I use them less, but templates are a great way to learn.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>There are many more tips, but they won’t be covered here.&lt;/p>
&lt;h2 id="learning-channels">
&lt;a class="heading-anchor-link" href="#learning-channels">Learning Channels&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="learning-channels"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>How to learn tips and tricks? The following channels are recommended:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://x.com/drawio" target="_blank" rel="noopener">Draw.io Official Twitter&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/@drawioapp" target="_blank" rel="noopener">Draw.io Official YouTube Channel&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="quickview-support">
&lt;a class="heading-anchor-link" href="#quickview-support">QuickView Support?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="quickview-support"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>It is not supported. So, if you want to preview locally, there are the following two methods:&lt;/p>
&lt;ol>
&lt;li>Install plugins in IDEs like VSC/JB to open it.&lt;/li>
&lt;li>Open it with the local Draw.io app.&lt;/li>
&lt;li>Directly export as an image to open.&lt;/li>
&lt;/ol>
&lt;h2 id="at-the-end">
&lt;a class="heading-anchor-link" href="#at-the-end">At the end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="at-the-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Draw.io is a free and excellent drawing software, and I recommend that everyone try it.&lt;/p></description></item><item><title>Trip to Shenyang, Liaoning</title><link>https://en.1991421.cn/2024/08/06/shenyang-trip/</link><pubDate>Tue, 06 Aug 2024 22:55:06 +0800</pubDate><guid>https://en.1991421.cn/2024/08/06/shenyang-trip/</guid><description>&lt;blockquote>
&lt;p>I spent August 2–5 wandering around Shenyang. A few observations worth recording.&lt;/p>
&lt;/blockquote>
&lt;img src="https://static.1991421.cn/2024/2024-08-06-232343.jpeg" alt="Shenyang street" style="zoom:50%;" />
&lt;h2 id="lodging">
&lt;a class="heading-anchor-link" href="#lodging">Lodging&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="lodging"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I usually default to Hanting when I travel.&lt;/p>
&lt;ol>
&lt;li>Breakfast is convenient but mediocre—this branch had a tiny spread and bland food.&lt;/li>
&lt;li>Staff were friendly and efficient when I needed help (room change, extra hangers, etc.).&lt;/li>
&lt;li>Sound insulation was terrible—the worst I’ve experienced at a Hanting.&lt;/li>
&lt;li>Room hardware felt tired: the shower diverter jammed, the door card didn’t work on first entry, so I ended up switching rooms. To their credit, the staff resolved everything quickly.&lt;/li>
&lt;/ol>
&lt;p>Summer vacation crowds meant the hotel was busy.&lt;/p>
&lt;h2 id="night-and-morning-markets">
&lt;a class="heading-anchor-link" href="#night-and-morning-markets">Night and morning markets&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="night-and-morning-markets"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Shenyang leans into its night/early-market culture. I made it to &lt;strong>Tawan Night Market&lt;/strong>, &lt;strong>Xita Night Market&lt;/strong>, &lt;strong>Laobeishi Night Market&lt;/strong>, &lt;strong>Caita Night Market&lt;/strong>, and &lt;strong>Xiaoheyuan Morning Market&lt;/strong>—lots of good food.&lt;/p>
&lt;p>Tawan was my favorite: tasty and reasonably priced. Laobeishi felt overpriced. Personal highlights: fried &lt;em>menzi&lt;/em> (a mung-bean starch dish) and giant pears.&lt;/p>
&lt;img src="https://static.1991421.cn/2024/2024-08-06-232511.jpeg" alt="Night market food" style="zoom:50%;" />
&lt;h2 id="transport">
&lt;a class="heading-anchor-link" href="#transport">Transport&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="transport"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Pedestrians frequently run red lights—saw it daily.&lt;/li>
&lt;li>Shenyang North Railway Station left a bad impression: only one restroom in the waiting area and no seating in the Beijing-bound hall.&lt;/li>
&lt;li>The subway is solid. Every station had a restroom, which was surprisingly convenient.&lt;/li>
&lt;/ol>
&lt;h2 id="sights">
&lt;a class="heading-anchor-link" href="#sights">Sights&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="sights"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Heat and limited time meant I only visited the Liaoning Provincial Museum, Shenyang Imperial Palace, and Shenyang Museum. The rest of the time I strolled and hunted for snacks.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Shenyang’s night markets are the standout—so much good food. Beyond that, the city didn’t completely win me over this time.&lt;/p></description></item><item><title>Large File Downloads with StreamSaver.js</title><link>https://en.1991421.cn/2024/07/26/streamsaver-js/</link><pubDate>Fri, 26 Jul 2024 22:21:14 +0800</pubDate><guid>https://en.1991421.cn/2024/07/26/streamsaver-js/</guid><description>&lt;blockquote>
&lt;p>If you use the blob object for browser-side file downloads and then call the URL.createObjectURL(blob) method, the file will be downloaded directly. However, the downside is that it only supports small file downloads. How can we solve this without changing the backend? StreamSaver.js was created to address this issue.&lt;/p>
&lt;/blockquote>
&lt;h2 id="principle">
&lt;a class="heading-anchor-link" href="#principle">Principle&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="principle"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>StreamSaver.js uses ServiceWorker to intercept requests. If the result of the request is a stream, it can be continuously written to the local browser side. This breaks the limitation of JS single-thread, allowing large file downloads without blocking the thread.&lt;/p>
&lt;h2 id="usage">
&lt;a class="heading-anchor-link" href="#usage">Usage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">streamSaver&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;streamsaver&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">streamSaver&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">mitm&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;https://example.com/custom_mitm.html&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">fileStream&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">streamSaver&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">createWriteStream&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;hello.mkv&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">size&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">10_000_000&lt;/span> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">fileWriter&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">fileStream&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">getWriter&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">fileWriter&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span> &lt;span class="nx">Uint8Array&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">chunk&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">fileWriter&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">close&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="browser-compatibility">
&lt;a class="heading-anchor-link" href="#browser-compatibility">Browser Compatibility&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="browser-compatibility"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since StreamSaver.js uses ServiceWorker, it is not supported in browsers that do not support ServiceWorker. For example, Firefox versions below 100 do not support WritableStream and require a polyfill to solve this issue.&lt;/p>
&lt;p>&lt;a href="https://unpkg.com/web-streams-polyfill@4.0.0/dist/polyfill.js" target="_blank" rel="noopener">https://unpkg.com/web-streams-polyfill@4.0.0/dist/polyfill.js&lt;/a>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-07-26-223435.jpeg"
alt="https://static.1991421.cn/2024/2024-07-26-223435.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="at-the-end">
&lt;a class="heading-anchor-link" href="#at-the-end">At the end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="at-the-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The above is just one method for large file downloads. Additionally, the server can directly support stream downloads. Which solution to use depends on the specific scenario.&lt;/p></description></item><item><title>Handling Errors in Streaming Responses</title><link>https://en.1991421.cn/2024/07/14/request-stream-exception-handling/</link><pubDate>Sun, 14 Jul 2024 23:37:24 +0800</pubDate><guid>https://en.1991421.cn/2024/07/14/request-stream-exception-handling/</guid><description>&lt;blockquote>
&lt;p>AI APIs often return server-sent streams. When the server reports an error, the payload still arrives as a stream, so error handling differs from typical JSON responses.&lt;/p>
&lt;/blockquote>
&lt;h2 id="example">
&lt;a class="heading-anchor-link" href="#example">Example&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="example"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Using Axios as an example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">axios&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">post&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;http://api.com/v1/chat/completions&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">data&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">headers&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Authorization&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="sb">`Bearer xxxx`&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;Content-Type&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;application/json&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">responseType&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;stream&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">then&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">res&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="k">catch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kr">async&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">e&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">error&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">e&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isAxiosError&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">streamString&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">await&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nb">Promise&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">resolve&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">e&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">response&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">data&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">on&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;data&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">utf8Chunk&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">streamString&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="nx">utf8Chunk&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">on&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;end&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">error&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">JSON&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">streamString&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">resolve&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">error&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">e&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">throw&lt;/span> &lt;span class="nx">error&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In streaming mode you must consume the error payload through the same evented interface as normal data. Wrapping the listener with a &lt;code>Promise&lt;/code> ensures you capture the full string before parsing and rethrowing.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When dealing with streaming APIs, remember that error paths are still streams—structure your error handling accordingly.&lt;/p></description></item><item><title>Installing Flarum on CentOS 7</title><link>https://en.1991421.cn/2024/07/07/centos7flarum/</link><pubDate>Sun, 07 Jul 2024 22:33:45 +0800</pubDate><guid>https://en.1991421.cn/2024/07/07/centos7flarum/</guid><description>&lt;h2 id="installing-php-73">
&lt;a class="heading-anchor-link" href="#installing-php-73">Installing PHP 7.3&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installing-php-73"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">sudo yum install epel-release -y
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm -y
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo yum install yum-utils -y
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo yum-config-manager --enable remi-php73
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo yum install php php-cli php-fpm php-mysqlnd php-json php-opcache php-xml php-mbstring php-tokenizer php-curl php-zip php-gd -y
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Check version&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">php -v
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="mysql8">
&lt;a class="heading-anchor-link" href="#mysql8">MySQL8&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mysql8"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-2.noarch.rpm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yum install -y mysql-community-server
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Get temporary password&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">grep &lt;span class="s1">&amp;#39;temporary password&amp;#39;&lt;/span> /var/log/mysqld.log
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Initialize DB configuration&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="heading">
&lt;a class="heading-anchor-link" href="#heading">&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="heading"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h2 id="installing-the-forum">
&lt;a class="heading-anchor-link" href="#installing-the-forum">Installing the Forum&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installing-the-forum"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># flarum is the folder under the current directory&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">composer create-project flarum/flarum flarum
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="caddy">
&lt;a class="heading-anchor-link" href="#caddy">Caddy&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="caddy"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here I use Caddy&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-caddy" data-lang="caddy">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Forum
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="gh">forum.xxx.cn&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">root&lt;/span> &lt;span class="nd">*&lt;/span> &lt;span class="s">/var/www/flarum/public&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">php_fastcgi&lt;/span> &lt;span class="s">unix//var/run/php-fpm/php-fpm.sock&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">header&lt;/span> &lt;span class="nd">/assets/*&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">+Cache-Control&lt;/span> &lt;span class="s2">&amp;#34;public, must-revalidate, proxy-revalidate&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">+Cache-Control&lt;/span> &lt;span class="s2">&amp;#34;max-age=25000&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">Pragma&lt;/span> &lt;span class="s2">&amp;#34;public&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">file_server&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="installing-flarum-plugins">
&lt;a class="heading-anchor-link" href="#installing-flarum-plugins">Installing Flarum Plugins&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installing-flarum-plugins"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Chinese language pack&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">composer require flarum-lang/chinese-simplified
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Upload plugin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">composer require fof/upload
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># sitemap&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">composer require fof/sitemap
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>After installing plugins, you need to enable the corresponding plugins in the admin panel.&lt;/p>
&lt;h2 id="data-backup">
&lt;a class="heading-anchor-link" href="#data-backup">Data Backup&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="data-backup"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Copy the &lt;code>vendor&lt;/code> folder, &lt;code>composer.json&lt;/code>, and &lt;code>composer.lock&lt;/code> to the newly built flarum folder on the new server.&lt;/li>
&lt;li>Export the entire database and then import it into the new server.&lt;/li>
&lt;/ol>
&lt;h2 id="related-documentation">
&lt;a class="heading-anchor-link" href="#related-documentation">Related Documentation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documentation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://phoenixnap.com/kb/how-to-install-and-use-php-composer-on-centos-7" target="_blank" rel="noopener">https://phoenixnap.com/kb/how-to-install-and-use-php-composer-on-centos-7&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://docs.flarum.org/zh/install/" target="_blank" rel="noopener">https://docs.flarum.org/zh/install/&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://discuss.flarum.org.cn" target="_blank" rel="noopener">https://discuss.flarum.org.cn&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Line Separators in Text Files</title><link>https://en.1991421.cn/2024/06/30/line-separators/</link><pubDate>Sun, 30 Jun 2024 12:29:08 +0800</pubDate><guid>https://en.1991421.cn/2024/06/30/line-separators/</guid><description>&lt;blockquote>
&lt;p>When processing text files, we encounter different line separators. Why do these differences exist and how should we handle them? Let me note this down here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="system-differences">
&lt;a class="heading-anchor-link" href="#system-differences">System Differences&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="system-differences"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Windows uses \r\n, while Unix/macOS uses \n&lt;/p>
&lt;p>For example, when creating a text file in Windows using NotePad, after saving and dragging it to editors like VSC, you can see the separator is indicated as \r\n.&lt;/p>
&lt;h2 id="editor-settings">
&lt;a class="heading-anchor-link" href="#editor-settings">Editor Settings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="editor-settings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In editors, we also see explanations about Line Separators.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-06-30-121405.jpeg"
alt="https://static.1991421.cn/2024/2024-06-30-121405.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>When we open files in editors like WebStorm or VSC, we also see such prompts in the status bar, telling you what the line separator of this file is.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-06-30-121555.jpeg"
alt="https://static.1991421.cn/2024/2024-06-30-121555.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="program-text-processing">
&lt;a class="heading-anchor-link" href="#program-text-processing">Program Text Processing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="program-text-processing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Different separators result in different text files, which can also cause exceptions in actual code processing. What if we want to handle this compatibly? For example, when processing text strings to arrays, we can use regex to solve this problem.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">str&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\r?\n/&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Done.&lt;/p></description></item><item><title>Z-Library &amp; Telegram: eBook Downloads</title><link>https://en.1991421.cn/2024/05/02/5ae61aa/</link><pubDate>Thu, 02 May 2024 10:04:15 +0800</pubDate><guid>https://en.1991421.cn/2024/05/02/5ae61aa/</guid><description>&lt;blockquote>
&lt;p>In my opinion, downloading e-book by Z-Library combined with Telegram will have the most comfortable experience. Just mark it here.&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>Visit &lt;a href="https://z-library.sk/" target="_blank" rel="noopener">https://z-library.sk/&lt;/a>
&lt;ol>
&lt;li>If you don&amp;rsquo;t have an account, register one.&lt;/li>
&lt;li>If access fails, suggest to try using a proxy.&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Go to &lt;a href="https://z-library.sk/z-access#telegram_bot_tab" target="_blank" rel="noopener">https://z-library.sk/z-access#telegram_bot_tab&lt;/a> to create a TG Bot.&lt;/li>
&lt;li>Once the TG Bot is successfully created, you can search for any book on your private Bot and click &amp;ldquo;download&amp;rdquo;.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-05-02-101044.jpeg"
alt="https://static.1991421.cn/2024/2024-05-02-101044.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Note that the daily download resource is limited.&lt;/strong>&lt;/p></description></item><item><title>Xbox Remote Play</title><link>https://en.1991421.cn/2024/05/01/xbox/</link><pubDate>Wed, 01 May 2024 14:17:17 +0800</pubDate><guid>https://en.1991421.cn/2024/05/01/xbox/</guid><description>&lt;blockquote>
&lt;p>If you want to play your home Xbox/PS games while away, one option is remote play. Here’s how to set it up with Xbox as an example.&lt;/p>
&lt;/blockquote>
&lt;h2 id="setup">
&lt;a class="heading-anchor-link" href="#setup">Setup&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="setup"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Router: enable &lt;code>UPnP&lt;/code>. DMZ is not required.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Enable remote features on Xbox&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Devices &amp;amp; connections → Remote features → Enable remote features&lt;/p>
&lt;/li>
&lt;li>
&lt;p>General → Network settings → Test NAT type should be [Open]&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>You should now see related entries appear under step 2.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-04-30-204834.jpeg"
alt="https://static.1991421.cn/2024/2024-04-30-204834.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>On an external network device (e.g., iPhone), sign in to Xbox and choose your console → Remote play.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-05-01-152355.jpeg"
alt="https://static.1991421.cn/2024/2024-05-01-152355.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="public-ip">
&lt;a class="heading-anchor-link" href="#public-ip">Public IP?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="public-ip"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In testing, a public IP is not required. As long as the console has outbound internet connectivity, remote play works.&lt;/p>
&lt;h2 id="current-issue">
&lt;a class="heading-anchor-link" href="#current-issue">Current Issue&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-issue"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>On mobile, if Surge proxy is enabled, remote play may fail to connect even with direct rules. Disabling Surge resolves it.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The steps are similar for PlayStation — just enable remote features and you’re set.&lt;/p></description></item><item><title>Automatic Review for User-Uploaded Images</title><link>https://en.1991421.cn/2024/04/29/image-censorship/</link><pubDate>Mon, 29 Apr 2024 22:31:27 +0800</pubDate><guid>https://en.1991421.cn/2024/04/29/image-censorship/</guid><description>&lt;blockquote>
&lt;p>Recently, I received news that the image upload feature in my project needs to undergo security review. After solving this problem, I’m marking it down here.&lt;/p>
&lt;p>I’m currently using Tencent Cloud’s COS-CDN, so I’ll use this product as an example to introduce the process.&lt;/p>
&lt;/blockquote>
&lt;h2 id="current-cos-usage">
&lt;a class="heading-anchor-link" href="#current-cos-usage">Current COS usage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-cos-usage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Images are currently uploaded via COS, which returns a path after storage. I use COS with a bound domain name through CDN for users to access.&lt;/p>
&lt;h2 id="review-configuration">
&lt;a class="heading-anchor-link" href="#review-configuration">Review configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="review-configuration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>COS supports configuring automatic image review. Since my COS also contains other resources, I enabled COS path restrictions for automatic image review—for example, only images in the /user-images path are reviewed.&lt;/li>
&lt;li>Since my image upload function was already online before, I needed to handle two types of images: existing and new ones
&lt;ol>
&lt;li>Existing images are reviewed by configuring a task for COS to review them again&lt;/li>
&lt;li>For new images, I use the COS SDK, which automatically triggers review after upload&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Configure actions for non-compliant reviews. Considering that user images might be misjudged or the current standards are too strict, I configured the system to automatically move non-compliant images to a specified directory so there’s still a chance to recover them.&lt;/li>
&lt;li>Since the review is configured to be post-upload, the COS upload environment doesn’t know if the image is non-compliant. Therefore, if you want to notify users about non-compliant images in your project, you still need to call the review API yourself or configure a review callback API. Otherwise, the upload will succeed without any violation notification, but the image will return 404 when accessed because it was processed after the post-upload review.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Now I understand how to use image review and have solved the requirement. However, I have to say that these needs are really driven by the domestic environment&amp;hellip;&lt;/p></description></item><item><title>First Experience Recycling an MBP via Xianyu</title><link>https://en.1991421.cn/2024/04/20/xianyu-recycling/</link><pubDate>Sat, 20 Apr 2024 15:11:58 +0800</pubDate><guid>https://en.1991421.cn/2024/04/20/xianyu-recycling/</guid><description>&lt;blockquote>
&lt;p>I’ve got a new MBP now, so I decided to recycle my 2019 model for some cash back — better than letting it gather dust.&lt;/p>
&lt;/blockquote>
&lt;h2 id="device">
&lt;a class="heading-anchor-link" href="#device">Device&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="device"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>MacBook Pro 2019 / 16 GB RAM / 512 GB SSD / i7. Purchased in 2021, no hidden issues.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-02-212048.jpeg"
alt="https://static.1991421.cn/2021/2021-01-02-212048.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>The 2019 model still looks great, but for my usage it stutters fairly often.&lt;/strong>&lt;/p>
&lt;h2 id="xianyu-recycle-vs-jd-recycle">
&lt;a class="heading-anchor-link" href="#xianyu-recycle-vs-jd-recycle">Xianyu recycle vs. JD recycle&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xianyu-recycle-vs-jd-recycle"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I first tried JD’s recycle program via their PC site; the quote was under ¥3,000 even “after applying coupons”. I figured Xianyu’s official recycle might offer more, so I tried that next.&lt;/p>
&lt;h2 id="xianyu-process">
&lt;a class="heading-anchor-link" href="#xianyu-process">Xianyu process&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xianyu-process"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>First, here’s how the Xianyu process goes 👇&lt;/p>
&lt;ol>
&lt;li>Get an in‑app quote and book pickup.&lt;/li>
&lt;li>Sign out of your Apple ID on the MBP.&lt;/li>
&lt;li>SF Express picks it up from your door.
&lt;ul>
&lt;li>No need to include accessories like the charger; no packaging needed — the courier handles it.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>After pickup they send an initial payment (I got a bit over ¥1,000).&lt;/li>
&lt;li>They do inspection → confirm final price → transfer the balance.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-17-100402.jpeg"
alt="https://static.1991421.cn/2025/2025-05-17-100402.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>If you’re mailing the machine, record a video beforehand to avoid disputes if they later claim “issues found”.&lt;/p>
&lt;h2 id="why-i-declined-xianyus-offer">
&lt;a class="heading-anchor-link" href="#why-i-declined-xianyus-offer">Why I declined Xianyu’s offer&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-i-declined-xianyus-offer"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Following the process, I shipped it — but the price got lowballed. Xianyu support called with a quote a bit over ¥1,000, rattling off issues I didn’t really follow. Crucially, it was far below the app estimate — a harsh cut — so I refused and asked for a return.
Then they called back offering a “special” extra ¥400–¥500, raising it to the ¥2,000+ range. At that point it wasn’t much different from JD, but the bargaining felt excessive, so I declined.&lt;/p>
&lt;p>&lt;strong>If a simple refusal gets an extra ¥400–¥500, that says a lot about the haggling. Major turn‑off.&lt;/strong>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-17-095353.jpeg"
alt="https://static.1991421.cn/2025/2025-05-17-095353.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-choice--jd-aihuishou">
&lt;a class="heading-anchor-link" href="#final-choice--jd-aihuishou">Final choice — JD Aihuishou&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-choice--jd-aihuishou"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since leaving it unused has little value, I ended up going with JD Aihuishou, placing the order online and completing the deal in person.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-17-082917.jpeg"
alt="https://static.1991421.cn/2025/2025-05-17-082917.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>My Xianyu recycle experience was poor — maybe it was “just my case,” but still.&lt;/li>
&lt;li>For maximum payout, selling directly on Xianyu second‑hand is likely best — if you have the time and patience.&lt;/li>
&lt;li>If you don’t want the hassle (my case), JD Aihuishou with in‑person handoff is the most convenient, albeit at a lower price.&lt;/li>
&lt;li>Alternatively, gifting the old laptop to family/friends is nice — no payment avoids later disputes.&lt;/li>
&lt;/ol></description></item><item><title>Enable IPv6 on Home Broadband</title><link>https://en.1991421.cn/2024/04/20/ipv6/</link><pubDate>Sat, 20 Apr 2024 13:02:42 +0800</pubDate><guid>https://en.1991421.cn/2024/04/20/ipv6/</guid><description>&lt;blockquote>
&lt;p>I saw posts saying IPv6 livestreams are more stable, so I upgraded my home network. Here’s the process.&lt;/p>
&lt;/blockquote>
&lt;h2 id="hardware">
&lt;a class="heading-anchor-link" href="#hardware">Hardware&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="hardware"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Hardware involved:&lt;/p>
&lt;ul>
&lt;li>China Unicom ONT&lt;/li>
&lt;li>ZTE router&lt;/li>
&lt;li>Clients (Mac, Apple TV, iPhone, etc.)&lt;/li>
&lt;/ul>
&lt;h2 id="bridge-the-ont">
&lt;a class="heading-anchor-link" href="#bridge-the-ont">Bridge the ONT&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bridge-the-ont"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Record your PPPoE username/password first—you’ll need them later.&lt;/p>
&lt;p>Report a “broadband issue” via the China Unicom app; the technician will call and switch the ONT to bridge mode remotely. If devices still connect afterward, bridging failed—ask them to retry or visit in person.&lt;/p>
&lt;p>Forgot the credentials? Call 010-112, then press 0 for a human agent.&lt;/p>
&lt;h2 id="router-pppoe-setup">
&lt;a class="heading-anchor-link" href="#router-pppoe-setup">Router PPPoE Setup&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="router-pppoe-setup"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Configure PPPoE on the router with the same credentials, ensuring IPv4 works first.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-04-20-131124.jpeg"
alt="https://static.1991421.cn/2024/2024-04-20-131124.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="enable-ipv6-on-the-router">
&lt;a class="heading-anchor-link" href="#enable-ipv6-on-the-router">Enable IPv6 on the Router&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="enable-ipv6-on-the-router"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>On my ZTE router I had to enable IPv6 in two places:&lt;/p>
&lt;ul>
&lt;li>System → IPv6 (toggle on)&lt;/li>
&lt;li>WAN → IPv6 (toggle on)&lt;/li>
&lt;/ul>
&lt;p>Then reboot the router.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-04-20-150202.jpeg"
alt="https://static.1991421.cn/2024/2024-04-20-150202.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="test-ipv6">
&lt;a class="heading-anchor-link" href="#test-ipv6">Test IPv6&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="test-ipv6"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Connect a device and visit &lt;a href="https://test-ipv6.com/" target="_blank" rel="noopener">https://test-ipv6.com/&lt;/a>&lt;/p>
&lt;p>If it reports an IPv6 address, you’re set.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-04-20-131411.jpeg"
alt="https://static.1991421.cn/2024/2024-04-20-131411.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>On macOS/iOS, check network details for an IPv6 address.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-04-20-131535.jpeg"
alt="https://static.1991421.cn/2024/2024-04-20-131535.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Note:&lt;/strong> If you proxy through Surge, enable &lt;code>ipv6-vif&lt;/code>; otherwise test-ipv6.com fails.&lt;/p>
&lt;h2 id="putting-ipv6-to-use">
&lt;a class="heading-anchor-link" href="#putting-ipv6-to-use">Putting IPv6 to Use&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="putting-ipv6-to-use"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Livestream sources labeled “IPv6” now play smoothly on Apple TV (iPlayTV). IPv6-only URLs work as well, e.g.:&lt;/p>
&lt;p>http://[2409:8087:1a01:df::7005]/ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226450/index.m3u8&lt;/p>
&lt;h2 id="closing-thoughts">
&lt;a class="heading-anchor-link" href="#closing-thoughts">Closing Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="closing-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Dual-stack devices keep IPv4, so enabling IPv6 has no downside—worth doing if your ISP supports it.&lt;/p></description></item><item><title>TinyMCE's GPL License Explained (Simple Guide)</title><link>https://en.1991421.cn/2024/04/13/98329e86/</link><pubDate>Sat, 13 Apr 2024 11:25:13 +0800</pubDate><guid>https://en.1991421.cn/2024/04/13/98329e86/</guid><description>&lt;blockquote>
&lt;p>TinyMCE is a veteran editor. When I looked into it, I noticed it uses the &lt;a href="https://github.com/tinymce/tinymce/blob/main/LICENSE.md" target="_blank" rel="noopener">GNU GPL&lt;/a>. That led me to ask: can I use it commercially? Can I fork it? Time to unpack GPL.&lt;/p>
&lt;/blockquote>
&lt;h2 id="explanation">
&lt;a class="heading-anchor-link" href="#explanation">Explanation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="explanation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here&amp;rsquo;s a summary adapted from a Zhihu answer:&lt;/p>
&lt;p>The GPL&amp;rsquo;s purpose is to ensure code remains open source and free to use. Its defining trait is the &lt;strong>copyleft effect&lt;/strong>—if a company ships a product using GPL code, in theory it must open-source its own codebase as well.&lt;/p>
&lt;p>Emphasis on “in theory.” Large companies often have ways to sidestep the requirement. In 2015, for example, Xiaomi was accused of violating the GPL. MIUI builds on Android, whose kernel is GPL-licensed Linux, so MIUI should be open-sourced. Xiaomi&amp;rsquo;s reply? “We&amp;rsquo;ll open source it soon,” then delayed indefinitely without outright denial.&lt;/p>
&lt;h2 id="example">
&lt;a class="heading-anchor-link" href="#example">Example&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="example"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Consider a commercial SaaS product using TinyMCE. You must follow TinyMCE&amp;rsquo;s licensing terms. GPLv2 allows the usage, but only if you meet certain conditions:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Distributing source code:&lt;/strong> If you modify TinyMCE, you must provide those modifications to anyone who receives your product. If you don&amp;rsquo;t plan to ship the site’s source, this might not apply—provided you never touch TinyMCE&amp;rsquo;s source.&lt;/li>
&lt;li>&lt;strong>Copyleft clause:&lt;/strong> Any derivative of TinyMCE must also be licensed under GPLv2. If integrating TinyMCE makes your site a derivative work, you would need to publish the site&amp;rsquo;s source under GPLv2. There&amp;rsquo;s debate about whether loading TinyMCE via JavaScript counts as a derivative; some say no if it runs as a separate program.&lt;/li>
&lt;li>&lt;strong>Dynamic linking:&lt;/strong> If your site links to TinyMCE dynamically (for example, through JavaScript), it&amp;rsquo;s often treated as separate, which might sidestep the copyleft. Interpretations differ, so legal advice is best to ensure compliance.&lt;/li>
&lt;li>Because your site is publicly accessible, review GPLv2 carefully and consider legal counsel so you don&amp;rsquo;t unintentionally violate the license.&lt;/li>
&lt;/ul>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If my web project relies on the GPL version of TinyMCE—even with no modifications—I&amp;rsquo;m still required to follow the GPL, meaning the whole project must be open source. The alternative is to obtain a commercial license.&lt;/p>
&lt;p>So, for commercial work where I want guaranteed compliance, the GPL build of TinyMCE is not the safe route.&lt;/p>
&lt;h2 id="other-open-source-editors">
&lt;a class="heading-anchor-link" href="#other-open-source-editors">Other Open Source Editors&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other-open-source-editors"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>There are other solid options besides TinyMCE.&lt;/p>
&lt;p>For example, monaco-editor uses the MIT license, so it&amp;rsquo;s freely usable in commercial products. Visual Studio Code&amp;rsquo;s editor is built on Monaco.&lt;/p>
&lt;h2 id="related-docs">
&lt;a class="heading-anchor-link" href="#related-docs">Related Docs&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-docs"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://github.com/tinymce/tinymce" target="_blank" rel="noopener">https://github.com/tinymce/tinymce&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.tiny.cloud/docs/tinymce/7/full-featured-premium-demo/" target="_blank" rel="noopener">https://www.tiny.cloud/docs/tinymce/7/full-featured-premium-demo/&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.gnu.org/licenses/gpl-3.0.html" target="_blank" rel="noopener">https://www.gnu.org/licenses/gpl-3.0.html&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://sogrey.top/article/%E4%B8%80%E5%BC%A0%E5%9B%BE%E5%BC%84%E6%87%82%E5%BC%80%E6%BA%90%E5%8D%8F%E8%AE%AE-GPL%E3%80%81BSD%E3%80%81MIT%E3%80%81Mozilla%E3%80%81Apache%E5%92%8CLGPL-%E4%B9%8B%E9%97%B4%E7%9A%84%E5%B7%AE%E5%88%AB/" target="_blank" rel="noopener">一张图弄懂开源协议-GPL、BSD、MIT、Mozilla、Apache和LGPL 之间的差别&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Product Documentation Writing Guidelines</title><link>https://en.1991421.cn/2024/03/14/36426150/</link><pubDate>Thu, 14 Mar 2024 09:57:26 +0800</pubDate><guid>https://en.1991421.cn/2024/03/14/36426150/</guid><description>&lt;blockquote>
&lt;p>Beyond in‑product help, we publish standalone product docs. Here are conventions I learned while writing docs at my company.&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>
&lt;p>Use respectful “您” rather than “你”.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Avoid arrows in screenshots; mosaics and red highlight boxes are fine.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Include static images and animated GIFs where helpful.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>External links are okay.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>End sentences with periods, including bullet items.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Start each document with a brief overview.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Steps should begin after login and include the full path to the feature, not just a partial step.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>In Chinese docs, add spaces around embedded English words.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Bold action nouns (menu items, buttons) to highlight them.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Use full‑width punctuation (colons, parentheses) for Chinese; half‑width for English.&lt;/p>
&lt;/li>
&lt;/ol></description></item><item><title>How to Use Eudic Dictionary (Step-by-Step Guide)</title><link>https://en.1991421.cn/2024/02/12/eudic-usage-guide/</link><pubDate>Mon, 12 Feb 2024 08:57:09 +0800</pubDate><guid>https://en.1991421.cn/2024/02/12/eudic-usage-guide/</guid><description>&lt;blockquote>
&lt;p>Since 2017, Eudic Dictionary has become my go-to dictionary app. Here&amp;rsquo;s an introduction to Eudic.&lt;/p>
&lt;/blockquote>
&lt;h2 id="cross-platform">
&lt;a class="heading-anchor-link" href="#cross-platform">Cross-Platform&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cross-platform"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Eudic supports major systems including Mac/Win/Linux. I primarily use it on the following platforms:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>iPhone &lt;code>Daily Use&lt;/code>&lt;/p>
&lt;p>Eudic has both free and enhanced versions &lt;code>98 CNY&lt;/code>. I currently use the free version, which also supports loading third-party dictionaries.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Mac &lt;code>Daily Use&lt;/code>&lt;/p>
&lt;p>Has both free and enhanced versions &lt;code>168 CNY&lt;/code>. I currently use the enhanced version because the free version doesn&amp;rsquo;t support loading third-party dictionaries.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>iPad &lt;code>Occasional Use&lt;/code>&lt;/p>
&lt;p>Authorized with the same iPhone account. I currently use the free version, which also supports loading third-party dictionaries.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>All paid versions are for permanent use with free upgrades.&lt;/p>
&lt;h2 id="features">
&lt;a class="heading-anchor-link" href="#features">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I primarily use the word lookup and translation services. Of course, Eudic also has other features like vocabulary notes and encyclopedia.&lt;/p>
&lt;h2 id="configuration">
&lt;a class="heading-anchor-link" href="#configuration">Configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="configuration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Notes:&lt;/p>
&lt;ul>
&lt;li>Eudic configurations may vary slightly across different clients&lt;/li>
&lt;li>The following are my personal setting preferences, use as needed&lt;/li>
&lt;/ul>
&lt;h3 id="custom-dictionary-library">
&lt;a class="heading-anchor-link" href="#custom-dictionary-library">Custom Dictionary Library&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="custom-dictionary-library"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;code>Eudic doesn't support dictionary synchronization, so Mac and iOS need to add dictionaries separately&lt;/code>. Eudic&amp;rsquo;s dictionary import creates a copy of the resources.&lt;/p>
&lt;p>I&amp;rsquo;ve added the following dictionaries:&lt;/p>
&lt;ol>
&lt;li>Oxford Advanced Learner&amp;rsquo;s Dictionary (Bilingual)&lt;/li>
&lt;li>Merriam-Webster&lt;/li>
&lt;/ol>
&lt;p>Dictionary resources can be found online.&lt;/p>
&lt;h4 id="adding-dictionaries-on-mac">Adding Dictionaries on Mac&lt;/h4>&lt;p>On the management page, simply drag the mdx file in. Eudic will automatically find the corresponding mdd files and other resource files for import.&lt;/p>
&lt;img src="https://static.1991421.cn/2024/2024-02-12-183019.png" alt="https://static.1991421.cn/2024/2024-02-12-183019.png" style="zoom:50%;" />
&lt;h4 id="adding-dictionaries-on-iphoneipad">Adding Dictionaries on iPhone/iPad&lt;/h4>&lt;p>For adding local dictionaries on iPhone/iPad, it&amp;rsquo;s recommended to add them directly through Mac Finder by dragging, or use third-party management clients like iMazing.&lt;/p>
&lt;p>The iOS version requires manually dragging and adding all resource files.&lt;/p>
&lt;img src="https://static.1991421.cn/2024/2024-02-12-194505.jpg" alt="https://static.1991421.cn/2024/2024-02-12-194505.jpg" style="zoom:40%;" />
&lt;h3 id="custom-translation">
&lt;a class="heading-anchor-link" href="#custom-translation">Custom Translation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="custom-translation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The translation services supported in Eudic like Tencent/Baidu/iFlytek/Youdao/Default Translation/Microsoft are all quite poor. The ones with OK quality are Eudic AI and DeepL.&lt;/p>
&lt;p>Through analysis, I believe Eudic AI uses OpenAI behind the scenes, but I don&amp;rsquo;t like Eudic reselling and making a profit margin here, so I recommend enabling DeepL translation &lt;code>free&lt;/code>. From screenshots, you can see that DeepL quality is still quite good.&lt;/p>
&lt;img src="https://static.1991421.cn/2024/2024-02-12-185347.png" alt="https://static.1991421.cn/2024/2024-02-12-185347.png" style="zoom:55%;" />
&lt;h3 id="disable-double-click-word-lookup-in-explanation-interface">
&lt;a class="heading-anchor-link" href="#disable-double-click-word-lookup-in-explanation-interface">Disable Double-Click Word Lookup in Explanation Interface&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="disable-double-click-word-lookup-in-explanation-interface"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>For Mac, I recommend turning off this setting because it&amp;rsquo;s easy to accidentally trigger during personal use. After disabling, it will also affect the translation page, but requires restarting Eudic.&lt;/p>
&lt;p>The similar setting on iOS is &lt;code>Single-click word lookup on explanation page&lt;/code>.&lt;/p>
&lt;h3 id="turn-off-lightpeek">
&lt;a class="heading-anchor-link" href="#turn-off-lightpeek">Turn off LightPeek&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="turn-off-lightpeek"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>For Mac, I recommend turning off this setting.&lt;/p>
&lt;h3 id="online-synchronization">
&lt;a class="heading-anchor-link" href="#online-synchronization">Online Synchronization&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="online-synchronization"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;blockquote>
&lt;p>The online synchronization feature saves your vocabulary book and note information to the network. It not only prevents data loss but also conveniently shares learning resources with your phone.&lt;/p>
&lt;/blockquote>
&lt;p>Here I recommend logging into your account across multiple devices.&lt;/p>
&lt;h3 id="combining-alfred-applescript">
&lt;a class="heading-anchor-link" href="#combining-alfred-applescript">Combining Alfred-AppleScript&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="combining-alfred-applescript"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Eudic has decent AppleScript support, so you can script word lookup/translation based on cursor-selected words. Here I use Alfred to implement one-click word lookup/pronunciation.&lt;/p>
&lt;p>Unfortunately, Eudic&amp;rsquo;s AppleScript doesn&amp;rsquo;t support calling translation.&lt;/p>
&lt;p>For specific configuration, you can refer to the article &lt;a href="https://1991421.cn/2019/11/03/be260ba50480/" target="_blank" rel="noopener">Using Alfred for Efficient Word Lookup with Eudic Dictionary&lt;/a>&lt;/p>
&lt;h2 id="eudic-vs-others">
&lt;a class="heading-anchor-link" href="#eudic-vs-others">Eudic vs Others&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="eudic-vs-others"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The reasons I use Eudic are mainly several aspects:&lt;/p>
&lt;ol>
&lt;li>Cross-platform - I have high-frequency usage needs on iPhone/Mac&lt;/li>
&lt;li>No ads/few ads - I&amp;rsquo;ve been using the free version on iOS and haven&amp;rsquo;t noticed any ads. The startup screen is also clean, unlike domestic apps&lt;/li>
&lt;li>Customization support - Eudic supports loading third-party dictionaries/AppleScript. A certain degree of customization means you can optimize usage habits according to your own preferences&lt;/li>
&lt;/ol>
&lt;h2 id="other-issues">
&lt;a class="heading-anchor-link" href="#other-issues">Other Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="to-buy-or-not-to-buy">
&lt;a class="heading-anchor-link" href="#to-buy-or-not-to-buy">To Buy or Not to Buy?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="to-buy-or-not-to-buy"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>As mentioned above, we understand the differences between free and paid versions on various platforms. For me, adding third-party dictionaries is important, which is why I bought the Mac enhanced version, while other platforms remain on the free version. If there are no special needs, I don&amp;rsquo;t recommend paying, because the free version is sufficient.&lt;/p>
&lt;h3 id="mdd-mdx">
&lt;a class="heading-anchor-link" href="#mdd-mdx">mdd, mdx&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mdd-mdx"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I see online resources have these two types of files, with a big size difference, where mdd is larger. What&amp;rsquo;s the difference between them, and should we import which one or both?&lt;/p>
&lt;p>Mdict dictionary files are generally composed of mdd and mdx. Some dictionaries will have css files to adjust the dictionary appearance, and some even have js files to implement more awesome features. Therefore, both types of files &lt;code>need to be imported&lt;/code>.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-02-12-201710.jpeg"
alt="https://static.1991421.cn/2024/2024-02-12-201710.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="shortcomings">
&lt;a class="heading-anchor-link" href="#shortcomings">Shortcomings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="shortcomings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here are a few shortcomings I&amp;rsquo;ve noticed with Eudic in actual use:&lt;/p>
&lt;ol>
&lt;li>Custom translation isn&amp;rsquo;t truly custom - there are only a few translation services included, and they&amp;rsquo;re all poor quality. User choices are too limited. Fortunately there&amp;rsquo;s DeepL, otherwise we&amp;rsquo;d have to buy AI translation. If Eudic really wants customization, they should integrate OpenAI and domestic AI services.&lt;/li>
&lt;li>Limited AppleScript support - currently only supports word lookup and pronunciation, translation isn&amp;rsquo;t supported&lt;/li>
&lt;li>Incomplete account synchronization - for example, custom translation engine settings aren&amp;rsquo;t synchronized&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Eudic does have shortcomings, but it excels in being simple and clean, ad-free, and having certain extensibility. Therefore, I still like it a lot and recommend everyone give it a try.&lt;/p>
&lt;h2 id="related-links">
&lt;a class="heading-anchor-link" href="#related-links">Related Links&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-links"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.eudic.net/v4/en/app/eudic" target="_blank" rel="noopener">Eudic Official Website&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.eudic.net/v4/en/home/detail" target="_blank" rel="noopener">&amp;ldquo;Eudic Dictionary&amp;rdquo;, &amp;ldquo;French Assistant&amp;rdquo;, &amp;ldquo;German Assistant&amp;rdquo;, &amp;ldquo;Spanish Assistant&amp;rdquo; Registration FAQ&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Comprehensive Introduction to Fig</title><link>https://en.1991421.cn/2024/01/28/fig-intro/</link><pubDate>Sun, 28 Jan 2024 22:29:06 +0800</pubDate><guid>https://en.1991421.cn/2024/01/28/fig-intro/</guid><description>&lt;blockquote>
&lt;p>Fig is a tool designed to enhance command-line efficiency and collaboration. It offers a range of features. Recently, due to work requirements, I&amp;rsquo;ve gained a relatively comprehensive understanding of Fig, so I&amp;rsquo;m documenting it here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="update-fig--amazon">
&lt;a class="heading-anchor-link" href="#update-fig--amazon">Update: Fig &amp;raquo; Amazon&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="update-fig--amazon"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>On 08/28/2023, Fig was acquired by Amazon, which demonstrates Fig&amp;rsquo;s value.&lt;/p>
&lt;p>&lt;a href="https://fig.io/blog/post/fig-joins-aws" target="_blank" rel="noopener">https://fig.io/blog/post/fig-joins-aws&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Currently, Fig has been sunsetted. Downloading Fig from the official website now redirects to CodeWhisperer. However, the completion experience remains consistent, with the main difference being the removal of non-completion features.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="fig-supported-platforms">
&lt;a class="heading-anchor-link" href="#fig-supported-platforms">Fig Supported Platforms&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="fig-supported-platforms"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Currently only supports &lt;code>Mac&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Linux is still under development, with current status available at:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://github.com/withfig/fig/issues/34" target="_blank" rel="noopener">https://github.com/withfig/fig/issues/34&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://fig.io/user-manual/linux" target="_blank" rel="noopener">https://fig.io/user-manual/linux&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="additional-features-beyond-completion">
&lt;a class="heading-anchor-link" href="#additional-features-beyond-completion">Additional Features Beyond Completion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="additional-features-beyond-completion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Dotfiles&lt;/li>
&lt;li>Scripts&lt;/li>
&lt;/ol>
&lt;h2 id="completion-mechanism">
&lt;a class="heading-anchor-link" href="#completion-mechanism">Completion Mechanism&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="completion-mechanism"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Traditional command completion is installed on the target machine, but many command-line tools either lack completion support or have fragmented support when installed. Fig addresses this by implementing the solution on the client side. After installation, Fig essentially loads predefined completion specifications on the client, prompting users to select appropriate command options, and then writing them back to the original terminal when Enter is pressed. This cycle repeats to solve the problem of difficult command input. The advantage of this approach is speed, though it does consume some performance and storage space since more commands need to be loaded as the user&amp;rsquo;s command repertoire grows.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>How Fig achieves cross-terminal completion GUI display:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The GUI itself is built using frontend JS/HTML/CSS&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Terminal interaction is achieved through a combination of shell function hooks, accessibility positioning, and frontend completion display&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="fig-resources">
&lt;a class="heading-anchor-link" href="#fig-resources">Fig Resources&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="fig-resources"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Fig is not just an App; over the years it has contributed a set of valuable resources&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Completion Specifications&lt;/p>
&lt;p>The specifications loaded in the App come from here, and with the power of the GitHub community, they are continuously updated. If you want to build a completion tool, you can directly use these specifications, meaning the Fig App is also a user of these specifications.&lt;/p>
&lt;p>&lt;a href="https://github.com/withfig/autocomplete" target="_blank" rel="noopener">https://github.com/withfig/autocomplete&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Completion Specification Scaffolding&lt;/p>
&lt;p>&lt;a href="https://github.com/withfig/autocomplete-tools" target="_blank" rel="noopener">https://github.com/withfig/autocomplete-tools&lt;/a>&lt;/p>
&lt;p>For contributing specifications, debugging specifications, etc., you can use the official completion tools.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Command Manual&lt;/p>
&lt;p>To see which commands Fig includes, you can check here:&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>​ &lt;a href="https://fig.io/manual" target="_blank" rel="noopener">https://fig.io/manual&lt;/a>&lt;/p>
&lt;h2 id="products-using-fig-completion-specifications">
&lt;a class="heading-anchor-link" href="#products-using-fig-completion-specifications">Products Using Fig Completion Specifications&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="products-using-fig-completion-specifications"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Warp&lt;/p>
&lt;/li>
&lt;li>
&lt;p>inshellisense&lt;/p>
&lt;/li>
&lt;li>
&lt;p>XTerminal&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Fig is an App, and its most important feature is command completion.&lt;/p>
&lt;p>Fig&amp;rsquo;s most valuable aspect isn&amp;rsquo;t the App itself, but rather the establishment of a complete set of completion specification protocols. Leveraging community power, it has contributed 500+ command completion specifications. If we&amp;rsquo;re talking about subcommands, that&amp;rsquo;s 28k (currently), which is excellent. This is likely why it was acquired by Amazon.&lt;/p>
&lt;h2 id="related-links">
&lt;a class="heading-anchor-link" href="#related-links">Related Links&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-links"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;a href="https://fig.io/blog" target="_blank" rel="noopener">https://fig.io/blog&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/withfig" target="_blank" rel="noopener">https://github.com/withfig&lt;/a>&lt;/li>
&lt;/ol></description></item><item><title>Microsoft Remote Desktop URL Scheme</title><link>https://en.1991421.cn/2024/01/23/microsoft-remote-desktopurl-scheme/</link><pubDate>Tue, 23 Jan 2024 21:56:38 +0800</pubDate><guid>https://en.1991421.cn/2024/01/23/microsoft-remote-desktopurl-scheme/</guid><description>&lt;blockquote>
&lt;p>In development, I hope users can launch the RDP app with one click on a web page. URL schemes seem like the answer.&lt;/p>
&lt;p>Tests show that RDP URL Scheme support is incomplete.&lt;/p>
&lt;/blockquote>
&lt;h2 id="platform">
&lt;a class="heading-anchor-link" href="#platform">Platform&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="platform"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>macOS&lt;/p>
&lt;p>System versions behave differently. Verified: Big Sur works.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">rdp://full%20address=s:&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&amp;amp;username=s:Administrator
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Click to test: &lt;code>rdp://full%20address=s:49.232.185.70:3389&amp;amp;username=s:Administrator&lt;/code>&lt;/p>
&lt;p>(Copy and paste the above URL into your browser address bar to test)&lt;/p>
&lt;p>Sonoma does not work.&lt;/p>
&lt;blockquote>
&lt;p>Failed to launch &amp;lsquo;rdp://full%20address=s:127.0.0.1:3389&amp;amp;username=s:Administrator&amp;rsquo; because the scheme does not have a registered handler.&lt;/p>
&lt;/blockquote>
&lt;p>Manually install &lt;a href="https://learn.microsoft.com/zh-cn/windows-server/remote/remote-desktop-services/clients/remote-desktop-mac" target="_blank" rel="noopener">RDP&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Windows&lt;/p>
&lt;p>Only supports launching the RDP client; parameters cannot be passed.&lt;/p>
&lt;p>Click to test: &lt;code>ms-rd://&lt;/code>&lt;/p>
&lt;p>(Copy and paste the above URL into your browser address bar to test)&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="rdp-file-download">
&lt;a class="heading-anchor-link" href="#rdp-file-download">RDP file download&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="rdp-file-download"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The most reliable approach is to let users download the &lt;code>.rdp&lt;/code> file and open it manually. The file content is:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">full address:s:9.9.9.9:3389
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">username:s:administrator
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Note: macOS requires manual installation of &lt;code>Microsoft Remote Desktop&lt;/code>.&lt;/p>
&lt;h2 id="docs">
&lt;a class="heading-anchor-link" href="#docs">Docs&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="docs"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://learn.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-uri" target="_blank" rel="noopener">https://learn.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-uri&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Nine Years with My Mountain Bike</title><link>https://en.1991421.cn/2024/01/21/my-mtb-9-years/</link><pubDate>Sun, 21 Jan 2024 23:06:35 +0800</pubDate><guid>https://en.1991421.cn/2024/01/21/my-mtb-9-years/</guid><description>&lt;blockquote>
&lt;p>I&amp;rsquo;ve had this mountain bike for quite some years now. I got it around 2015 - a Merida Duke 600, cost 2500 CNY with a lock included. I&amp;rsquo;m still riding it today.&lt;/p>
&lt;p>Here I&amp;rsquo;ll summarize the accessories I&amp;rsquo;ve purchased and my thoughts on the bike/brand&lt;/p>
&lt;/blockquote>
&lt;img src="https://static.1991421.cn/2024/2024-01-21-231442.jpeg" alt="https://static.1991421.cn/2024/2024-01-21-231442.jpeg" style="zoom: 50%;" />
&lt;h2 id="accessories">
&lt;a class="heading-anchor-link" href="#accessories">Accessories&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here are the ones I commonly use:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Folding combination lock&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Xiaomi portable air pump&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Half-finger/full-finger gloves&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Tire valve caps&lt;/p>
&lt;p>The valve caps will get damaged over time, so you can buy these third-party ones - they&amp;rsquo;re good quality and look better too&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Bicycle chain lubricant&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Seat cover&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Bell&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="companion-apps">
&lt;a class="heading-anchor-link" href="#companion-apps">Companion Apps&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="companion-apps"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Cycling often needs apps to make it more interesting.&lt;/p>
&lt;ol>
&lt;li>Route tracking: I still recommend Xingzhe, although I&amp;rsquo;ve stopped using it myself due to &lt;code>ads and bloat&lt;/code>, and now just use Apple Watch Workout directly.&lt;/li>
&lt;li>Daily navigation: Gaode Maps, of course&lt;/li>
&lt;/ol>
&lt;h2 id="brandbike-quality">
&lt;a class="heading-anchor-link" href="#brandbike-quality">Brand/Bike Quality&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="brandbike-quality"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After riding for 9 years, the quality is indeed quite good. Apart from changing tires, I haven&amp;rsquo;t done any repairs. However, I will consider switching to other brands in the future for two reasons:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>There are too few brand stores in Beijing - at least none near me, which makes bike maintenance inconvenient. Many shops only service their own brands.&lt;/p>
&lt;p>Of course, for minor issues, I still recommend tinkering with it yourself to exercise your hands-on skills&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Official accessories are not abundant&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="common-problems">
&lt;a class="heading-anchor-link" href="#common-problems">Common Problems&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-problems"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Wheel falling off&lt;/p>
&lt;p>Quick-release lever loosened and not properly tightened&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>When the weather warms up, I&amp;rsquo;ll continue cycling to and from work&amp;hellip;&lt;/li>
&lt;/ol>
&lt;h2 id="related-links">
&lt;a class="heading-anchor-link" href="#related-links">Related Links&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-links"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://github.com/alanhe421/others-note/issues/522" target="_blank" rel="noopener">https://github.com/alanhe421/others-note/issues/522&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Writing TypeScript in Monaco Editor</title><link>https://en.1991421.cn/2024/01/20/monaco-editorts/</link><pubDate>Sat, 20 Jan 2024 22:26:34 +0800</pubDate><guid>https://en.1991421.cn/2024/01/20/monaco-editorts/</guid><description>&lt;blockquote>
&lt;p>Providing a high-quality TypeScript editing experience in Monaco Editor on the web requires specific configurations. Here are some key tips:&lt;/p>
&lt;/blockquote>
&lt;h3 id="1-set-the-language-to-typescript">
&lt;a class="heading-anchor-link" href="#1-set-the-language-to-typescript">1. Set the Language to TypeScript&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="1-set-the-language-to-typescript"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>When initializing the editor instance, ensure the language is set correctly:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">monaco&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">editor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">create&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">document&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">getElementById&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;container&amp;#39;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">value&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;const x: number = 10;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">language&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;typescript&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-add-custom-type-declarations-typings">
&lt;a class="heading-anchor-link" href="#2-add-custom-type-declarations-typings">2. Add Custom Type Declarations (Typings)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2-add-custom-type-declarations-typings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>To provide IntelliSense for external libraries or custom interfaces, use &lt;code>addExtraLib&lt;/code>. This allows the editor to recognize types that aren&amp;rsquo;t defined in the current file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">monaco&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">languages&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">typescript&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">typescriptDefaults&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">addExtraLib&lt;/span>&lt;span class="p">([&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;declare class MyLibrary {&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39; static doSomething(): void;&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;}&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">].&lt;/span>&lt;span class="nx">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;\n&amp;#39;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="s1">&amp;#39;filename/to/mylib.d.ts&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="3-essential-editor-settings">
&lt;a class="heading-anchor-link" href="#3-essential-editor-settings">3. Essential Editor Settings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="3-essential-editor-settings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Common UI settings that improve the developer experience:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Minimap&lt;/strong>: Toggle the code overview on the side.&lt;/li>
&lt;li>&lt;strong>Theme&lt;/strong>: Switch between &amp;lsquo;vs&amp;rsquo; (light), &amp;lsquo;vs-dark&amp;rsquo;, or &amp;lsquo;hc-black&amp;rsquo;.&lt;/li>
&lt;li>&lt;strong>Automatic Layout&lt;/strong>: Enable &lt;code>automaticLayout: true&lt;/code> so the editor resizes with its container.&lt;/li>
&lt;/ul>
&lt;p>These configurations transform a basic text area into a powerful IDE-like environment right in the browser.&lt;/p></description></item><item><title>Mastering Fig: Custom Autocomplete Specifications</title><link>https://en.1991421.cn/2024/01/18/90190e56/</link><pubDate>Thu, 18 Jan 2024 15:44:08 +0800</pubDate><guid>https://en.1991421.cn/2024/01/18/90190e56/</guid><description>&lt;blockquote>
&lt;p>While the Fig interface is sleek, its real value resides in the &lt;strong>specification (spec) definitions&lt;/strong>. These specs tell Fig how to interpret commands and provide intelligent completions. This post covers the workflow for customizing these specs and bringing them into your production environment.&lt;/p>
&lt;/blockquote>
&lt;h3 id="anatomy-of-a-fig-spec">
&lt;a class="heading-anchor-link" href="#anatomy-of-a-fig-spec">Anatomy of a Fig Spec&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="anatomy-of-a-fig-spec"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>A Fig spec is a TypeScript file that defines the structure of a CLI tool, including its subcommands, options, and arguments. Here are some examples from the official repository:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;code>cd&lt;/code> command&lt;/strong>: &lt;a href="https://github.com/withfig/autocomplete/blob/master/src/cd.ts" target="_blank" rel="noopener">cd.ts&lt;/a>&lt;/li>
&lt;li>&lt;strong>&lt;code>git&lt;/code> command&lt;/strong>: &lt;a href="https://github.com/withfig/autocomplete/blob/master/src/git.ts" target="_blank" rel="noopener">git.ts&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>You can find the underlying Type definitions in the &lt;a href="https://github.com/withfig/autocomplete-tools/blob/main/types/index.d.ts" target="_blank" rel="noopener">autocomplete-tools repo&lt;/a>.&lt;/p>
&lt;hr>
&lt;h2 id="1-contributing-to-the-official-repository">
&lt;a class="heading-anchor-link" href="#1-contributing-to-the-official-repository">1. Contributing to the Official Repository&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="1-contributing-to-the-official-repository"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If your CLI tool is public, the best approach is to contribute directly to the &lt;a href="https://github.com/withfig/autocomplete" target="_blank" rel="noopener">withfig/autocomplete&lt;/a> repo. Once merged, your completions become available to all Fig users.&lt;/p>
&lt;h3 id="the-development-workflow">
&lt;a class="heading-anchor-link" href="#the-development-workflow">The Development Workflow:&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-development-workflow"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Fork and Clone&lt;/strong>: Fork the repository and clone your fork locally.&lt;/li>
&lt;li>&lt;strong>Setup&lt;/strong>: Add the original repo as a remote and install dependencies.
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git remote add upstream https://github.com/withfig/autocomplete.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pnpm install
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>&lt;strong>Create a Spec&lt;/strong>: Use the Fig CLI to scaffold a new spec (e.g., for a tool called &lt;code>mytool&lt;/code>).
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pnpm create-spec mytool
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>&lt;strong>Developer Mode&lt;/strong>: Enable &lt;code>dev&lt;/code> mode. This tells your local Fig instance to load specs from your current directory instead of the global cache.
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pnpm dev
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;h2 id="2-managing-private-or-internal-specs">
&lt;a class="heading-anchor-link" href="#2-managing-private-or-internal-specs">2. Managing Private or Internal Specs&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2-managing-private-or-internal-specs"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you&amp;rsquo;re building completions for private internal tools, you don&amp;rsquo;t want to submit them to the public repo. Instead, you can manage them in your own standalone project.&lt;/p>
&lt;h3 id="standalone-setup">
&lt;a class="heading-anchor-link" href="#standalone-setup">Standalone Setup:&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="standalone-setup"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Scaffold the project&lt;/strong>:
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npx @withfig/autocomplete-tools create-spec
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>&lt;strong>Build and Register&lt;/strong>: Running the &lt;code>dev&lt;/code> command will compile your TypeScript spec and register it with Fig.
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npx @withfig/autocomplete-tools dev
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;h3 id="example-spec-structure">
&lt;a class="heading-anchor-link" href="#example-spec-structure">Example Spec Structure:&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="example-spec-structure"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Here is a basic template for a custom completion spec:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">completionSpec&lt;/span>: &lt;span class="kt">Fig.Spec&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;mytool&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">summary&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;A powerful internal dev tool&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">subcommands&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;deploy&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">summary&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Deploy the project to production&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">options&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;--force&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;-f&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="nx">summary&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Force deployment&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">options&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;--help&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;-h&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="nx">summary&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Show help information&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">export&lt;/span> &lt;span class="k">default&lt;/span> &lt;span class="nx">completionSpec&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="developer-mode-toggles">
&lt;a class="heading-anchor-link" href="#developer-mode-toggles">Developer Mode Toggles&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="developer-mode-toggles"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>To test your specs, you must ensure your terminal environment is in developer mode.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>In Amazon CodeWhisperer (which acquired Fig)&lt;/strong>: Toggle this through the application settings UI.&lt;/li>
&lt;li>&lt;strong>Via CLI&lt;/strong>: Use the following command to toggle the NPM developer mode:
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">fig settings autocomplete.developerModeNPM &lt;span class="nb">true&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-01-18-160706.jpeg"
alt="Fig Dev Mode in Action"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="summary">
&lt;a class="heading-anchor-link" href="#summary">Summary&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="summary"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>By mastering Fig specs, you can transform your command line from a blank prompt into an intelligent, guided experience. Whether you&amp;rsquo;re helping the global community or just streamlining your team&amp;rsquo;s internal tools, custom specs are the key to a faster CLI workflow.&lt;/p></description></item><item><title>Fig Completion Specification - Filter Highlight</title><link>https://en.1991421.cn/2024/01/15/fig-completion-highlight/</link><pubDate>Mon, 15 Jan 2024 21:10:53 +0800</pubDate><guid>https://en.1991421.cn/2024/01/15/fig-completion-highlight/</guid><description>&lt;blockquote>
&lt;p>When using Fig, as data is continuously entered, suggestions are continuously filtered and highlighted. Actual testing and analysis revealed the highlighting logic.&lt;/p>
&lt;/blockquote>
&lt;h2 id="logic">
&lt;a class="heading-anchor-link" href="#logic">Logic&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="logic"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>While generating the completion list, calculate N characters from current input command cursor to start matching, defined as charactersToDrop=N&lt;/li>
&lt;li>Split N characters into character array, each character performs match highlighting using lazy matching&lt;/li>
&lt;li>When user presses enter, terminal first deletes N characters, then writes the matched completion value&lt;/li>
&lt;li>User presses enter to select suggestion&lt;/li>
&lt;/ol>
&lt;h2 id="example">
&lt;a class="heading-anchor-link" href="#example">Example&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="example"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Input &lt;code>cd ar&lt;/code>, charactersToDrop=2&lt;/p>
&lt;p>Each character performs matching. After &amp;lsquo;a&amp;rsquo; matches, &amp;lsquo;r&amp;rsquo; continues to match, but &amp;lsquo;r&amp;rsquo; must match after &amp;lsquo;a&amp;rsquo;&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-01-15-211931.jpeg"
alt="https://static.1991421.cn/2024/2024-01-15-211931.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p></description></item><item><title>How to Use YouTube Kids (Step-by-Step Guide)</title><link>https://en.1991421.cn/2024/01/01/youtube-kids/</link><pubDate>Mon, 01 Jan 2024 12:58:20 +0800</pubDate><guid>https://en.1991421.cn/2024/01/01/youtube-kids/</guid><description>&lt;blockquote>
&lt;p>We recently had kids over at home, and I wanted to play age‑appropriate videos on the TV. I discovered YouTube’s dedicated Kids section and, after some trial and error, found it quite good. Here’s how to use YouTube Kids.&lt;/p>
&lt;/blockquote>
&lt;img src="https://static.1991421.cn/2024/2024-01-01-122348.jpeg" alt="https://static.1991421.cn/2024/2024-01-01-122348.jpeg" style="zoom:50%;" />
&lt;h2 id="introduction">
&lt;a class="heading-anchor-link" href="#introduction">Introduction&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="introduction"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>YouTube Kids is a free app designed for children, providing a safer environment for browsing YouTube videos. It offers kid‑friendly content and tools for parents to control what their children watch.&lt;/p>
&lt;h2 id="requirements">
&lt;a class="heading-anchor-link" href="#requirements">Requirements&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="requirements"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Same as YouTube:&lt;/p>
&lt;ul>
&lt;li>YouTube Kids is free; subscribers can remove ads.&lt;/li>
&lt;li>A network proxy may be needed depending on access restrictions.&lt;/li>
&lt;/ul>
&lt;h2 id="platforms">
&lt;a class="heading-anchor-link" href="#platforms">Platforms&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="platforms"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>iPhone&lt;/li>
&lt;li>Web&lt;/li>
&lt;li>Apple TV&lt;/li>
&lt;/ol>
&lt;p>It’s available across platforms, which is great.&lt;/p>
&lt;h2 id="using-on-apple-tv-atv">
&lt;a class="heading-anchor-link" href="#using-on-apple-tv-atv">Using on Apple TV (ATV)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="using-on-apple-tv-atv"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>My main use is on Apple TV.&lt;/p>
&lt;ol>
&lt;li>Download the Kids app on ATV&lt;/li>
&lt;li>After logging in, follow the prompts to activate and bind the device on iPhone/web
&lt;ul>
&lt;li>Activation URL: &lt;a href="https://kids.youtube.com/activate" target="_blank" rel="noopener">https://kids.youtube.com/activate&lt;/a>. iPhone activation didn’t work for me; the web worked. After activation, the app will prompt success.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-01-01-124242.png"
alt="https://static.1991421.cn/2024/2024-01-01-124242.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ol start="3">
&lt;li>The parental management page lets you set age, watch time, etc.
&lt;ul>
&lt;li>Web settings: &lt;a href="https://www.youtubekids.com/" target="_blank" rel="noopener">https://www.youtubekids.com/&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Tap the child profile to enter their recommendations page&lt;/li>
&lt;/ol>
&lt;h2 id="drawbacks">
&lt;a class="heading-anchor-link" href="#drawbacks">Drawbacks&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="drawbacks"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Not all videos have subtitles. While YouTube supports auto‑generated captions, Kids may not.&lt;/p>
&lt;p>Some videos with Chinese subtitles:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.youtubekids.com/watch?v=9kobedlD0ac&amp;amp;hl=zh-TW" target="_blank" rel="noopener">Giwa&amp;rsquo;s Science&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>YouTube Kids is pretty good overall and worth a try.&lt;/li>
&lt;li>I previously tried YouTube Music as a music option and Studio as a content management platform. Kids is another focused product under YouTube.&lt;/li>
&lt;/ol>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/intl/ALL_tw/kids/" target="_blank" rel="noopener">https://www.youtube.com/intl/ALL_tw/kids/&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>The DOM Event Model</title><link>https://en.1991421.cn/2023/12/30/dom-event-mechanism/</link><pubDate>Sat, 30 Dec 2023 22:23:56 +0800</pubDate><guid>https://en.1991421.cn/2023/12/30/dom-event-mechanism/</guid><description>&lt;blockquote>
&lt;p>I’ve been wiring up keyboard shortcuts lately and needed a quick refresher on DOM events.&lt;/p>
&lt;/blockquote>
&lt;h2 id="event-flow-visualization">
&lt;a class="heading-anchor-link" href="#event-flow-visualization">Event Flow Visualization&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="event-flow-visualization"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;img src="https://www.w3.org/TR/DOM-Level-3-Events/images/eventflow.svg" style="width:50%;" />
&lt;h2 id="javascript-apis">
&lt;a class="heading-anchor-link" href="#javascript-apis">JavaScript APIs&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="javascript-apis"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Binding events is straightforward. Use &lt;code>addEventListener&lt;/code>, and pass the third argument to opt into the capture phase. For pure bubbling, handlers like &lt;code>onclick&lt;/code> work too.&lt;/li>
&lt;li>The &lt;code>event.stopPropagation()&lt;/code> method halts propagation—whether the event is bubbling or capturing—exactly as the diagram shows.&lt;/li>
&lt;li>&lt;code>event.preventDefault()&lt;/code> doesn’t stop propagation, but it blocks default behaviors such as following a link when clicking an &lt;code>&amp;lt;a&amp;gt;&lt;/code> tag.&lt;/li>
&lt;/ol>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.w3.org/TR/DOM-Level-3-Events/#event-flow" target="_blank" rel="noopener">https://www.w3.org/TR/DOM-Level-3-Events/#event-flow&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>done&lt;/p></description></item><item><title>How to Use inshellisense (Step-by-Step Guide)</title><link>https://en.1991421.cn/2023/12/25/inshellisense/</link><pubDate>Mon, 25 Dec 2023 22:34:10 +0800</pubDate><guid>https://en.1991421.cn/2023/12/25/inshellisense/</guid><description>&lt;blockquote>
&lt;p>IDE style command line auto complete&lt;/p>
&lt;/blockquote>
&lt;p>Hereafter, &lt;code>inshellisense&lt;/code> will be abbreviated as &lt;code>is&lt;/code>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/microsoft/inshellisense/blob/main/docs/demo.gif?raw=true"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="installation">
&lt;a class="heading-anchor-link" href="#installation">Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># If Node.js is not installed yet, recommended to install via nvm&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh &lt;span class="p">|&lt;/span> bash
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nvm install &lt;span class="m">18&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npm install -g @microsoft/inshellisense
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npm install -g node-gyp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Don&amp;rsquo;t worry about the &lt;code>npm WARN EBADENGINE required: { node: '&amp;gt;=18' }&lt;/code> warning during installation - it&amp;rsquo;s just the Fig specification recommending Node 18+. inshellisense supports Node 16, but higher versions are recommended.&lt;/p>
&lt;h3 id="node-21">
&lt;a class="heading-anchor-link" href="#node-21">Node &amp;lt;21&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="node-21"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Testing revealed that Node 21 installation fails because the dependency node-gyp doesn&amp;rsquo;t support version 21 yet.&lt;/p>
&lt;h2 id="usage">
&lt;a class="heading-anchor-link" href="#usage">Usage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Enter completion session, press space after typing commands to trigger completion popup&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">is
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Use complete subcommand to get JSON completion results (not supported in rc-5 yet)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">is &lt;span class="nb">complete&lt;/span> &lt;span class="s2">&amp;#34;git l&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol>
&lt;li>If it doesn&amp;rsquo;t enter normally, check for any error messages&lt;/li>
&lt;li>If it enters without errors but doesn&amp;rsquo;t trigger completion popup, it&amp;rsquo;s usually due to PS1 prompt detection issues. Official troubleshooting documentation is not yet available.
&lt;ul>
&lt;li>Personally encountered issues with &lt;code>powerlevel10k/powerlevel9k&lt;/code> themes in ZSH. Current solution is to switch themes.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="key-bindings">
&lt;a class="heading-anchor-link" href="#key-bindings">Key Bindings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="key-bindings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Currently, inshellisense does not support custom key bindings&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align: left">Action&lt;/th>
&lt;th style="text-align: left">Keybinding&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align: left">Accept Current Suggestion&lt;/td>
&lt;td style="text-align: left">&lt;kbd>tab&lt;/kbd>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: left">View Next Suggestion&lt;/td>
&lt;td style="text-align: left">&lt;kbd>↓&lt;/kbd>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: left">View Previous Suggestion&lt;/td>
&lt;td style="text-align: left">&lt;kbd>↑&lt;/kbd>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: left">Dismiss Suggestions&lt;/td>
&lt;td style="text-align: left">&lt;kbd>esc&lt;/kbd>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="supported-shells">
&lt;a class="heading-anchor-link" href="#supported-shells">Supported Shells&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="supported-shells"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">export&lt;/span> &lt;span class="kr">enum&lt;/span> &lt;span class="nx">Shell&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Bash&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;bash&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Powershell&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;powershell&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Pwsh&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;pwsh&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Zsh&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;zsh&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Fish&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;fish&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Cmd&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;cmd&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="project-overview">
&lt;a class="heading-anchor-link" href="#project-overview">Project Overview&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="project-overview"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;a href="https://github.com/microsoft/inshellisense" target="_blank" rel="noopener">https://github.com/microsoft/inshellisense&lt;/a>&lt;/p>
&lt;h3 id="tech-stack">
&lt;a class="heading-anchor-link" href="#tech-stack">Tech Stack&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tech-stack"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">&amp;#34;@withfig/autocomplete&amp;#34;: &amp;#34;^2.633.0&amp;#34;, # Fig completion specification
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;node-pty&amp;#34;: &amp;#34;^1.0.0&amp;#34;, # Fork pseudoterminals in Node.JS
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;xterm-headless&amp;#34;: &amp;#34;^5.3.0&amp;#34; # xterm.js headless terminal
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="project-structure">
&lt;a class="heading-anchor-link" href="#project-structure">Project Structure&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="project-structure"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-gdscript3" data-lang="gdscript3">&lt;span class="line">&lt;span class="cl">&lt;span class="err">├──&lt;/span> &lt;span class="n">shell&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">bash&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">preexec&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sh&lt;/span> &lt;span class="c1"># for bash, extended function hook support&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">shellIntegration&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">env&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zsh&lt;/span> &lt;span class="c1"># zsh&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">shellIntegration&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">login&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zsh&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">shellIntegration&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">profile&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zsh&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">shellIntegration&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">rc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zsh&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">shellIntegration&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">bash&lt;/span> &lt;span class="c1"># bash&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">shellIntegration&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fish&lt;/span> &lt;span class="c1"># fish&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">└──&lt;/span> &lt;span class="n">shellIntegration&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ps1&lt;/span> &lt;span class="c1"># for Windows Powershell/Pwsh&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">├──&lt;/span> &lt;span class="n">src&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">commands&lt;/span> &lt;span class="c1"># is command definitions&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">index&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ts&lt;/span> &lt;span class="c1"># entry point&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">isterm&lt;/span> &lt;span class="c1"># terminal emulator for is&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">runtime&lt;/span> &lt;span class="c1"># load specifications, get suggestions based on input&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">tests&lt;/span> &lt;span class="c1"># tests&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">├──&lt;/span> &lt;span class="n">ui&lt;/span> &lt;span class="c1"># terminal rendering and interaction (completion/uninstall prompts, etc.)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">│&lt;/span>   &lt;span class="err">└──&lt;/span> &lt;span class="n">utils&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="program-logic">
&lt;a class="heading-anchor-link" href="#program-logic">Program Logic&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="program-logic"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>process(&amp;lt;=&amp;gt;pty&amp;lt;=&amp;gt;xtermjs)&lt;/p>
&lt;ol>
&lt;li>
&lt;p>User enters command &lt;code>is&lt;/code> to enter auto-completion mode&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Load is configuration files&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Determine shell type&lt;/p>
&lt;ul>
&lt;li>User can specify shell in &lt;code>is&lt;/code> command, otherwise automatically determined from SHELL environment variable&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Initialize shell configuration&lt;/p>
&lt;ul>
&lt;li>For Zsh, add the following files to temporary directory:&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">- shellIntegration-env.zsh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- shellIntegration-login.zsh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- shellIntegration-profile.zsh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- shellIntegration-rc.zsh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>For Bash, add &lt;code>bash-preexec.sh&lt;/code> to user home directory&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Load full Fig specification in is&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Set &lt;code>process.stdin.setRawMode&lt;/code> to true to ensure each keypress triggers data events&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Execute clear screen&lt;/p>
&lt;/li>
&lt;li>
&lt;p>node-pty opens a pseudo terminal, loads corresponding shell configuration, and creates xterm headless terminal client&lt;/p>
&lt;/li>
&lt;li>
&lt;p>process.stdin.on(&amp;ldquo;data&amp;rdquo;) listens for user input and continuously writes to pty&lt;/p>
&lt;/li>
&lt;li>
&lt;p>pty listens for input, displays echo data, and writes to xterm&lt;/p>
&lt;/li>
&lt;li>
&lt;p>xterm listens for written data&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Calculate prompt start/end positions based on OSC in data. Command manager synchronizes terminal state&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Completion manager calculates completions and determines whether to display them&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Completion command module performs lexical analysis of commands, determines command context, and generates completions&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Completion generation depends on 3 factors: input, cwd, shell&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// input is current command: this.#term.getCommandState().commandText, process.cwd() is current path
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">getSuggestions&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">input&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">process&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">cwd&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Key bindings are also handled during character listening, e.g., tab writes completed command:&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>process.stdout writes to terminal&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="completion-calculation-logic">
&lt;a class="heading-anchor-link" href="#completion-calculation-logic">Completion Calculation Logic&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="completion-calculation-logic"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Analyze command text to determine token array&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">lex&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">command&lt;/span>: &lt;span class="kt">string&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">CommandToken&lt;/span>&lt;span class="p">[]&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">tokens&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>First token in array is rootToken, used to fetch completion files&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">loadSpec&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kr">async&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">cmd&lt;/span>: &lt;span class="kt">CommandToken&lt;/span>&lt;span class="p">[])&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">Promise&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">Fig.Spec&lt;/span> &lt;span class="err">|&lt;/span> &lt;span class="na">undefined&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">rootToken&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">cmd&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">at&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="nx">rootToken&lt;/span>&lt;span class="o">?&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">complete&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">loadedSpecs&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">rootToken&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">token&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">loadedSpecs&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">rootToken&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">token&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">specSet&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">rootToken&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">token&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">spec&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">await&lt;/span> &lt;span class="kr">import&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">specSet&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">rootToken&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">token&lt;/span>&lt;span class="p">])).&lt;/span>&lt;span class="k">default&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">loadedSpecs&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">rootToken&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">token&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">spec&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">spec&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Determine if last token in array is a path based on whether it contains /&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Calculate completions starting from second token in array&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Completion filtering&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="suggestion-data-definition">
&lt;a class="heading-anchor-link" href="#suggestion-data-definition">Suggestion Data Definition&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="suggestion-data-definition"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">export&lt;/span> &lt;span class="kr">type&lt;/span> &lt;span class="nx">Suggestion&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">name&lt;/span>: &lt;span class="kt">string&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">allNames&lt;/span>: &lt;span class="kt">string&lt;/span>&lt;span class="p">[];&lt;/span> &lt;span class="c1">// command parameters in Fig can have multiple names, e.g., [&amp;#34;-p&amp;#34;, &amp;#34;--paginate&amp;#34;] in git
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">description?&lt;/span>: &lt;span class="kt">string&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">icon&lt;/span>: &lt;span class="kt">string&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// emoji font
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">priority&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// priority, descending order in is
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">insertValue?&lt;/span>: &lt;span class="kt">string&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// actual value inserted into terminal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="debugging">
&lt;a class="heading-anchor-link" href="#debugging">Debugging&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="debugging"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>Directly execute &lt;code>npm ru debug&lt;/code>, then enable &lt;code>Attach to Node Process ⌘&lt;/code> in VSCode&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Check logs at &lt;code>~/.inshellisense/inshellisense.log&lt;/code>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Personally, I think the performance of this design approach for is is acceptable, but drawing completions directly in the terminal brings issues: if position calculation is incorrect, the cursor position can easily become misaligned&lt;/li>
&lt;li>Looking forward to is being officially released soon&lt;/li>
&lt;/ol></description></item><item><title>iframe-embedded code-server communication issues with host page</title><link>https://en.1991421.cn/2023/12/10/iframecode-server/</link><pubDate>Sun, 10 Dec 2023 20:51:10 +0800</pubDate><guid>https://en.1991421.cn/2023/12/10/iframecode-server/</guid><description>&lt;h2 id="background">
&lt;a class="heading-anchor-link" href="#background">Background&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="background"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>A web page embeds code-server web in an iframe, both pages are same-site, and now we need code-server to send messages to the host page after triggering operations.&lt;/li>
&lt;/ol>
&lt;h2 id="requirements">
&lt;a class="heading-anchor-link" href="#requirements">Requirements&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="requirements"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Customize code-server UI to support displaying buttons, such as in the top-right toolbar&lt;/li>
&lt;li>Enable communication between code-server and the host page&lt;/li>
&lt;/ol>
&lt;h2 id="solutions">
&lt;a class="heading-anchor-link" href="#solutions">Solutions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="solutions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>First, it&amp;rsquo;s important to understand code-server&amp;rsquo;s limitations: code-server extensions cannot add custom buttons in the title position. Through plugin solutions, only the bottom status bar and left activity buttons can be modified.&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Host page element rendering, positioned to move to code-server area&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Advantage&lt;/strong>: No need to customize code-server&lt;/li>
&lt;li>&lt;strong>Disadvantage&lt;/strong>: code-server&amp;rsquo;s title bar/layout controls can be freely toggled on/off. If turned off, it looks awkward and requires watching for display changes in the editor&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>code-server extension&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Register buttons in activity bar or add right-click menu directly in editor&lt;/li>
&lt;li>Register Actions&lt;/li>
&lt;li>When menu/button is clicked, Action executes and sends message to host page server&lt;/li>
&lt;li>Server sends message to host page frontend, which then executes related actions&lt;/li>
&lt;li>&lt;strong>Advantage&lt;/strong>: Flexible&lt;/li>
&lt;li>&lt;strong>Disadvantage&lt;/strong>: The communication chain is quite long&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="solution-2-details">
&lt;a class="heading-anchor-link" href="#solution-2-details">Solution 2 Details&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="solution-2-details"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Fetch requests: Node.js also has built-in fetch object, so the fetch solution can support extensions in both code-server and VS Code. However, the fetch solution is not bidirectional.&lt;/p>
&lt;h2 id="related-issues">
&lt;a class="heading-anchor-link" href="#related-issues">Related Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://github.com/coder/code-server/issues/621" target="_blank" rel="noopener">https://github.com/coder/code-server/issues/621&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/coder/code-server/discussions/4644" target="_blank" rel="noopener">https://github.com/coder/code-server/discussions/4644&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When dealing with iframe-embedded code-server communication, it&amp;rsquo;s crucial to consider the trade-offs between implementation complexity and flexibility. The extension-based approach, while more complex, offers better integration and maintainability in the long run. For simpler use cases, the host page element positioning approach might suffice, but be prepared to handle layout changes dynamically. Always test both same-origin and cross-origin scenarios to ensure robust communication channels.&lt;/p></description></item><item><title>Visiting China–Japan Friendship Hospital</title><link>https://en.1991421.cn/2023/12/09/hospital-visit-china-japan-friendship/</link><pubDate>Sat, 09 Dec 2023 18:31:06 +0800</pubDate><guid>https://en.1991421.cn/2023/12/09/hospital-visit-china-japan-friendship/</guid><description>&lt;blockquote>
&lt;p>I recently went to China‑Japan Friendship Hospital and hit several procedural pitfalls, ending up with multiple wasted trips. Here’s the process I wish I’d had.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-12-09-185534.jpeg"
alt="https://static.1991421.cn/2023/2023-12-09-185534.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="what-to-bring">
&lt;a class="heading-anchor-link" href="#what-to-bring">What to bring&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-to-bring"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>&lt;code>Medical insurance card&lt;/code> for partial reimbursement&lt;/p>
&lt;p>Optional — Alipay/WeChat e‑insurance also works&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>Phone&lt;/code> — for ticketing and paying for medication&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>ID card&lt;/code> just in case&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="full-visit-flow">
&lt;a class="heading-anchor-link" href="#full-visit-flow">Full visit flow&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="full-visit-flow"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Book via WeChat mini‑program “China–Japan Friendship Hospital” or the public account “Beijing 114 Appointment Registration”.
&lt;ul>
&lt;li>I recommend 114 for a better experience.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Go to &lt;code>Outpatient Building B, 2F&lt;/code> to get your number from a kiosk.&lt;/li>
&lt;li>Go to the department on your ticket → scan to check in → see the doctor.
&lt;ul>
&lt;li>Most clinics require QR check‑in — don’t skip it.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>After the visit, nearby kiosks support insurance/mobile payment. If e‑insurance scan fails, try switching between Alipay/WeChat.&lt;/li>
&lt;li>Print the invoice.
&lt;ul>
&lt;li>Nice touch: self‑service invoice printers (e.g., on 2F).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="things-i-found-unreasonable">
&lt;a class="heading-anchor-link" href="#things-i-found-unreasonable">Things I found unreasonable&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="things-i-found-unreasonable"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Doctors don’t proactively provide a printed visit record; some hospitals do.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>For reimbursement only, use the official mini‑program → Outpatient Services → Information Query → Outpatient Medical Record Query → select patient → view record.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-12-09-184724.jpeg"
alt="https://static.1991421.cn/2023/2023-12-09-184724.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>
&lt;p>Alipay e‑insurance scan error&lt;/p>
&lt;p>Try WeChat e‑insurance. I didn’t bring my card; kiosks showed Alipay e‑insurance but scanning failed. Switching to WeChat e‑insurance worked. The hospital should indicate “e‑insurance” generically, not just “Alipay”.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-12-09-190007.jpeg"
alt="https://static.1991421.cn/2023/2023-12-09-190007.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Restrooms are not clearly marked in the hallways; I had to ask staff in the outpatient building.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Every hospital is different — and often frustrating. Research the process to avoid extra trips.&lt;/li>
&lt;/ol></description></item><item><title>How to Use code-server (Step-by-Step Guide)</title><link>https://en.1991421.cn/2023/12/04/code-server/</link><pubDate>Mon, 04 Dec 2023 22:02:37 +0800</pubDate><guid>https://en.1991421.cn/2023/12/04/code-server/</guid><description>&lt;blockquote>
&lt;p>While developing a Web IDE, I discovered code-server. After using it for some time, I&amp;rsquo;m summarizing some issues encountered with code-server usage and customization.&lt;/p>
&lt;/blockquote>
&lt;h2 id="introduction">
&lt;a class="heading-anchor-link" href="#introduction">Introduction&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="introduction"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>code-server is the web version of &lt;code>Visual Studio Code&lt;/code>. In its architecture, code-server actually develops vsc as a submodule, so many features are compatible. If you need a powerful development experience that&amp;rsquo;s almost identical to vsc, then code-server is very suitable.&lt;/p>
&lt;h2 id="technology-behind-code-server">
&lt;a class="heading-anchor-link" href="#technology-behind-code-server">Technology Behind Code-Server&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="technology-behind-code-server"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>code-server is a Node.js program, but the installation package includes Node.js built-in, so you don&amp;rsquo;t need to manually install Node.js environment&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The code-server project itself depends on code (Visual Studio Code). This reveals that vsc is also based on Node.js, but the performance is actually quite good&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The editor part in code-server uses Monaco Editor, and the terminal part uses xterm.js. Both should be familiar, 😊.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="browser-support-list">
&lt;a class="heading-anchor-link" href="#browser-support-list">Browser Support List&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="browser-support-list"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>According to official sources, modern browsers are supported. Specific version requirements aren&amp;rsquo;t clearly defined yet, but from the technology stack perspective, it uses service workers.&lt;/p>
&lt;ul>
&lt;li>Chrome, Firefox, Safari, Edge&lt;/li>
&lt;/ul>
&lt;p>Nowadays, IE has exited the stage, Edge aligns with Chrome, so service worker support is not a problem anymore.&lt;/p>
&lt;h2 id="installation">
&lt;a class="heading-anchor-link" href="#installation">Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Use the official one-click installation script &lt;code>Cross-platform support&lt;/code>&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl"># Supports specifying version installation
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">curl -fsSL https://code-server.dev/install.sh | sh -s -- --version=4.7.1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Official documentation: &lt;a href="https://coder.com/docs/code-server/latest/install" target="_blank" rel="noopener">https://coder.com/docs/code-server/latest/install&lt;/a>&lt;/p>
&lt;p>Due to network issues in China, if installation fails, proceed with method 2&lt;/p>
&lt;ol start="2">
&lt;li>Use offline installation packages, pay attention to server architecture differences and choose appropriate packages&lt;/li>
&lt;/ol>
&lt;p>&lt;a href="https://github.com/coder/code-server/releases" target="_blank" rel="noopener">https://github.com/coder/code-server/releases&lt;/a>&lt;/p>
&lt;h3 id="distribution-package-differences">
&lt;a class="heading-anchor-link" href="#distribution-package-differences">Distribution Package Differences&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="distribution-package-differences"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">linux-amd64 represents 64-bit x86 architecture (typically called &amp;#34;PC&amp;#34; or &amp;#34;desktop&amp;#34;).
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">linux-arm64 represents 64-bit ARM architecture (typically used for servers, mobile devices, and embedded systems).
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">linux-armv7l represents 32-bit ARM architecture (typically used for older Raspberry Pi or similar devices).
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="running-in-background">
&lt;a class="heading-anchor-link" href="#running-in-background">Running in Background&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="running-in-background"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>Manually add to service&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">cat &amp;gt; /usr/lib/systemd/system/code-server.service &lt;span class="s">&amp;lt;&amp;lt; EOF
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">[Unit]
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">Description=code-server
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">After=network.target
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">[Service]
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">Type=exec
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">Environment=HOME=/root
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">ExecStart=/usr/bin/code-server
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">Restart=always
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">EOF&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">systemctl start code-server
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Disadvantage: Requires root privileges since it needs to be added to system startup services&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Supervisor&lt;/p>
&lt;p>Requires installing supervisor program, which depends on Python 2 environment. Advantage is that it doesn&amp;rsquo;t require root user privileges&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&amp;amp; background running&lt;/p>
&lt;p>Directly run `code-server &amp;amp;&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="login-authentication">
&lt;a class="heading-anchor-link" href="#login-authentication">Login Authentication&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="login-authentication"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>$HOME/.config/code-server/config.yaml&lt;/p>
&lt;h2 id="extensions">
&lt;a class="heading-anchor-link" href="#extensions">Extensions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="extensions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Multiple installation methods: offline installation by placing extensions in target directory, or directly search and install from marketplace when accessing code-server web interface&lt;/li>
&lt;/ol>
&lt;h2 id="code-server---help">
&lt;a class="heading-anchor-link" href="#code-server---help">code-server &amp;ndash;help&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="code-server---help"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Besides starting the service, code-server command can perform various operations&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl"># List all command properties
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">code-server --help
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># List installed extensions
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">code-server --list-extensions
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># Install extension
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">code-server --install-extension
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="common-issues">
&lt;a class="heading-anchor-link" href="#common-issues">Common Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="opening-specific-folder-by-default">
&lt;a class="heading-anchor-link" href="#opening-specific-folder-by-default">Opening Specific Folder by Default&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="opening-specific-folder-by-default"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Configure folder parameter in URL&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">http://127.0.0.1:8080/?folder=/Users/xxx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="opening-specific-line-and-column">
&lt;a class="heading-anchor-link" href="#opening-specific-line-and-column">Opening Specific Line and Column&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="opening-specific-line-and-column"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>code-server cli has -r parameter support: -r filename:row:column.&lt;/p>
&lt;p>Related community discussion &lt;a href="https://github.com/coder/code-server/discussions/5801" target="_blank" rel="noopener">coder/code-server#5801&lt;/a>&lt;/p>
&lt;h3 id="language-switching">
&lt;a class="heading-anchor-link" href="#language-switching">Language Switching&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="language-switching"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>After installing language packs, you can switch display language in the web interface. You can also set default language directly through configuration file, provided the corresponding language pack is installed&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">cat &lt;span class="s">&amp;lt;&amp;lt; EOF &amp;gt; $ROOT_PATH/.local/share/User/argv.json
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">{&amp;#34;locale&amp;#34;: &amp;#34;zh-cn&amp;#34;}
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">EOF&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Besides this method, another way is &lt;code>code-server --locale=zh-cn&lt;/code>&lt;/p>
&lt;p>Passing parameters directly via command line, disadvantage is it directly overwrites the original language setting, not recommended.&lt;/p>
&lt;h3 id="port-forwarding">
&lt;a class="heading-anchor-link" href="#port-forwarding">Port Forwarding&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="port-forwarding"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>In actual usage, noticed that when starting web under code-server, code-server itself performs port forwarding, which is also a configurable setting&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl"> // When enabled, new running processes will be detected and their listening ports will be automatically forwarded. Disabling this setting will not prevent all port forwarding. Even when disabled, extensions will still be able to cause ports to be forwarded, and opening certain URLs will still cause ports to be forwarded.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;remote.autoForwardPorts&amp;#34;: true,
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;a href="https://github.com/microsoft/vscode/issues/108346" target="_blank" rel="noopener">microsoft/vscode#108346&lt;/a>&lt;/p>
&lt;h3 id="heartbeat">
&lt;a class="heading-anchor-link" href="#heartbeat">Heartbeat&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="heartbeat"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Noticed that code-server periodically sends heartbeats to the server to ensure connection stability and avoid disconnections. By default, the heartbeat interval is 5 seconds.&lt;/p>
&lt;h3 id="main-page">
&lt;a class="heading-anchor-link" href="#main-page">Main Page&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="main-page"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>For example: &lt;code>code-server-4.8.3-2-linux-amd64/lib/vscode/out/vs/code/browser/workbench/workbench.html&lt;/code>&lt;/p>
&lt;h3 id="cdn">
&lt;a class="heading-anchor-link" href="#cdn">CDN&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cdn"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>code-server itself doesn&amp;rsquo;t support CDN configuration, but it can be solved by directly modifying workbench.html since all static resource entries are here. Simply change all static resource URLs to CDN resource addresses. Prerequisite is that all static resources in the program package are already hosted on CDN.&lt;/p>
&lt;p>When accessing code-server, the real dynamic content is mainly through 2 WebSocket requests and a few HTTP requests.&lt;/p>
&lt;h2 id="code-server-customization">
&lt;a class="heading-anchor-link" href="#code-server-customization">Code-Server Customization&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="code-server-customization"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>code-server itself doesn&amp;rsquo;t have much customization capability&lt;/p>
&lt;ol>
&lt;li>Through configuration files
&lt;ul>
&lt;li>i.e., VSC configuration files&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Logo and other information can only be changed by modifying source code&lt;/li>
&lt;li>Extensions can add IDE functionality and some UI changes, such as bottom status bar, left menu - this is consistent with local vsc&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you&amp;rsquo;re considering building a web IDE, you can try code-server&lt;/p>
&lt;h2 id="related-documentation">
&lt;a class="heading-anchor-link" href="#related-documentation">Related Documentation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documentation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>[Original issue][https://github.com/alanhe421/coding-note/issues/412]&lt;/li>
&lt;li>&lt;a href="https://github.com/coder/code-server" target="_blank" rel="noopener">https://github.com/coder/code-server&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>[https://github.com/alanhe421/coding-note/issues/412]:&lt;/p></description></item><item><title>Tools of the Year: 2023 Gear Review</title><link>https://en.1991421.cn/2023/12/03/2023/</link><pubDate>Sun, 03 Dec 2023 10:05:55 +0800</pubDate><guid>https://en.1991421.cn/2023/12/03/2023/</guid><description>&lt;blockquote>
&lt;p>Another year of hardware and software upgrades. Here’s a summary of my 2023 pickups.&lt;/p>
&lt;/blockquote>
&lt;h2 id="ezviz-c6c-home-security-camera">
&lt;a class="heading-anchor-link" href="#ezviz-c6c-home-security-camera">EZVIZ C6C Home Security Camera&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ezviz-c6c-home-security-camera"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in &lt;strong>January 2023&lt;/strong> for &lt;strong>233 CNY&lt;/strong>, including a 32GB SD card. I previously tried a Xiaomi camera, but the image quality was poor, and it bricked during a firmware update right out of the box. I returned it and went with EZVIZ.&lt;/p>
&lt;p>After a year of use, I&amp;rsquo;m very satisfied with the C6C. While the app experience could be more polished, it fulfills its purpose perfectly.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://user-images.githubusercontent.com/9245110/212689330-2d782269-6749-42c4-8f5e-b9f51f98ae08.png"
alt="EZVIZ C6C"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Check it out on JD.com: &lt;a href="https://item.jd.com/100029466747.html" target="_blank" rel="noopener">EZVIZ C6C&lt;/a>&lt;/p>
&lt;h2 id="niu-electric-scooter-mqil-urban-edition">
&lt;a class="heading-anchor-link" href="#niu-electric-scooter-mqil-urban-edition">NIU Electric Scooter (MQiL Urban Edition)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="niu-electric-scooter-mqil-urban-edition"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in &lt;strong>July 2023&lt;/strong> for &lt;strong>5,699 CNY&lt;/strong>.&lt;/p>
&lt;p>The overall experience has been great. I love being able to use my Apple Watch or iPhone to lock and unlock it, and the aesthetic is top-notch.&lt;/p>
&lt;h2 id="dyson-v8-vacuum-cleaner">
&lt;a class="heading-anchor-link" href="#dyson-v8-vacuum-cleaner">Dyson V8 Vacuum Cleaner&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="dyson-v8-vacuum-cleaner"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD in &lt;strong>September 2023&lt;/strong> for &lt;strong>1,989 CNY&lt;/strong>.&lt;/p>
&lt;p>Budget constraints led me to the V8, and it’s been fantastic. The suction is powerful, and it doubles as a handheld vacuum for cleaning sofas and mattresses.&lt;/p>
&lt;h2 id="logitech-m720-mouse">
&lt;a class="heading-anchor-link" href="#logitech-m720-mouse">Logitech M720 Mouse&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="logitech-m720-mouse"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD in &lt;strong>September 2023&lt;/strong> for &lt;strong>169 CNY&lt;/strong>. I love the multi-device switching feature; it makes managing two Macs simultaneously much easier.&lt;/p>
&lt;h2 id="loctek-electric-standing-desk-e5-n">
&lt;a class="heading-anchor-link" href="#loctek-electric-standing-desk-e5-n">Loctek Electric Standing Desk E5-N&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="loctek-electric-standing-desk-e5-n"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD in &lt;strong>September 2023&lt;/strong> for &lt;strong>2,071 CNY&lt;/strong>. It features four height presets and memory function. I love being able to switch to a standing position with a single click after sitting for a long time.&lt;/p>
&lt;p>I looked at IKEA options, but Loctek was more affordable and met all my stability and functional requirements.&lt;/p>
&lt;h2 id="apple-airtag">
&lt;a class="heading-anchor-link" href="#apple-airtag">Apple AirTag&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-airtag"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD in &lt;strong>June 2023&lt;/strong> for &lt;strong>178 CNY&lt;/strong>. I find it most useful on my keys. Whenever I can&amp;rsquo;t find them, I just ask Siri or use &amp;ldquo;Find My&amp;rdquo; to make them beep—it&amp;rsquo;s incredibly convenient.&lt;/p>
&lt;h2 id="airpods-3">
&lt;a class="heading-anchor-link" href="#airpods-3">AirPods 3&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="airpods-3"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD in &lt;strong>May 2023&lt;/strong> for &lt;strong>1,196 CNY&lt;/strong>. Typical Apple quality. I’ve upgraded from the 1st and 2nd gens and remain a loyal user.&lt;/p>
&lt;h2 id="bull-magsafe-power-bank-10000-mah">
&lt;a class="heading-anchor-link" href="#bull-magsafe-power-bank-10000-mah">Bull MagSafe Power Bank (10,000 mAh)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bull-magsafe-power-bank-10000-mah"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from Pinduoduo in &lt;strong>November 2023&lt;/strong> for &lt;strong>130 CNY&lt;/strong>. I really like the build quality. Wireless charging has been a game-changer—no more searching for cables. Compared to Anker, the Bull model is a bit thicker, but given Bull&amp;rsquo;s reputation for electrical products, I decided to give it a try and I&amp;rsquo;m happy with it.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-12-04-220104.jpeg"
alt="2023 Gear Review"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="asics-gt-2000-12">
&lt;a class="heading-anchor-link" href="#asics-gt-2000-12">ASICS GT-2000 12&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="asics-gt-2000-12"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased from JD in &lt;strong>October 2023&lt;/strong> for &lt;strong>519 CNY&lt;/strong>. This is my fourth pair of the ASICS GT-2000 series. While the newer designs since the 7th gen have improved comfort, they&amp;rsquo;ve sacrificed some breathability. Still, the overall comfort is excellent.&lt;/p>
&lt;h2 id="chatgpt-plus">
&lt;a class="heading-anchor-link" href="#chatgpt-plus">ChatGPT Plus&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="chatgpt-plus"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>$20/month&lt;/strong>. Absolutely worth it. Being able to access the latest GPT features as they release is fantastic. Compared to pay-as-you-go API costs, the unlimited (fair use) access is a steal.&lt;/p>
&lt;h2 id="github-copilot">
&lt;a class="heading-anchor-link" href="#github-copilot">GitHub Copilot&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="github-copilot"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>$10/month&lt;/strong>. An essential AI coding assistant. It even helps with writing Markdown documentation.&lt;/p>
&lt;h2 id="netflix">
&lt;a class="heading-anchor-link" href="#netflix">Netflix&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="netflix"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Currently using a shared family plan for &lt;strong>40 CNY/quarter&lt;/strong>. It&amp;rsquo;s great to have high-quality shows readily available without hunting for resources.&lt;/p></description></item><item><title>Nintendo Switch Online Membership Purchase</title><link>https://en.1991421.cn/2023/11/19/nintendo-switch-online/</link><pubDate>Sun, 19 Nov 2023 23:59:24 +0800</pubDate><guid>https://en.1991421.cn/2023/11/19/nintendo-switch-online/</guid><description>&lt;blockquote>
&lt;p>Online membership allows you to play classic mini-games like Double Dragon for free, and of course there are other benefits. Recently, because I wanted to play some mini-games, I subscribed to experience the membership.&lt;/p>
&lt;/blockquote>
&lt;h2 id="membership-subscription">
&lt;a class="heading-anchor-link" href="#membership-subscription">Membership Subscription&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="membership-subscription"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I chose the HK individual membership at &lt;code>25HKD/month&lt;/code>. Family membership offers better value, but requires more people for carpooling, so I didn&amp;rsquo;t bother with that.&lt;/p>
&lt;h3 id="payment-method">
&lt;a class="heading-anchor-link" href="#payment-method">Payment Method&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="payment-method"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Visa is supported, so you can simply bind a domestic credit card.&lt;/p>
&lt;ol>
&lt;li>Enter EShop on your Nintendo Switch&lt;/li>
&lt;li>Select Online&lt;/li>
&lt;li>Follow the instructions to subscribe&lt;/li>
&lt;/ol>
&lt;h2 id="canceling-subscription">
&lt;a class="heading-anchor-link" href="#canceling-subscription">Canceling Subscription&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="canceling-subscription"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Currently, canceling subscription needs to be done on the Nintendo Switch device. I couldn&amp;rsquo;t find an unsubscribe option on the website.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Enter EShop on your Nintendo Switch&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Click on your avatar&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Select Online&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Click Stop&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://www.nintendo.com.hk/support/switch/qna/img/35585-04.jpg"
alt="https://www.nintendo.com.hk/support/switch/qna/img/35585-04.jpg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="related-documentation">
&lt;a class="heading-anchor-link" href="#related-documentation">Related Documentation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documentation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.nintendo.com.hk/support/switch/qna_sub/35585.html" target="_blank" rel="noopener">https://www.nintendo.com.hk/support/switch/qna_sub/35585.html&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Netflix Membership Purchase</title><link>https://en.1991421.cn/2023/10/27/netflix/</link><pubDate>Fri, 27 Oct 2023 23:04:40 +0800</pubDate><guid>https://en.1991421.cn/2023/10/27/netflix/</guid><description>&lt;blockquote>
&lt;p>Currently, I mostly use Infuse+Aliyun Cloud Drive for watching movies, but finding resources can sometimes be troublesome, so considering getting Netflix membership here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-10-27-232730.jpg"
alt="https://static.1991421.cn/2023/2023-10-27-232730.jpg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="prerequisites">
&lt;a class="heading-anchor-link" href="#prerequisites">Prerequisites&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="prerequisites"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Proxy, whether carpooling or self-registering/paying/using, all require solving proxy&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Registration region corresponding country proxy IP/payment method&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="note">
&lt;a class="heading-anchor-link" href="#note">Note&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="note"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Netflix resources don&amp;rsquo;t follow the account but depend on proxy nodes. For example, Cybertron animation is available under HK proxy nodes. To specifically determine if resources are available in target region&lt;/p>
&lt;p>Can use this site to query: &lt;a href="https://unogs.com/" target="_blank" rel="noopener">https://unogs.com/&lt;/a>&lt;/p>
&lt;h2 id="current-solution---carpool-">
&lt;a class="heading-anchor-link" href="#current-solution---carpool-">Current Solution - Carpool 🚗&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-solution---carpool-"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Considering no proxy IP for countries like Pakistan, let alone payment bank cards, choosing carpool to solve the problem, after all personal Netflix demand isn&amp;rsquo;t that strong yet&lt;/p>
&lt;ol>
&lt;li>Telegram carpool - &lt;code>Pakistan&lt;/code>&lt;/li>
&lt;li>&lt;code>40CNY&lt;/code>/quarter&lt;/li>
&lt;li>Pakistan payment currency is Pakistani Rupee (PKR)&lt;/li>
&lt;/ol>
&lt;p>Sharing a daily carpool channel here 👉https://t.me/hezu2&lt;/p>
&lt;h2 id="usage-notes">
&lt;a class="heading-anchor-link" href="#usage-notes">Usage Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage-notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>First month cannot use Hong Kong proxy&lt;/p>
&lt;/li>
&lt;li>
&lt;p>From second month no HK restrictions&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Everyone shares same email/password, each uses one profile, recommend enabling PIN code for Profile&lt;/p>
&lt;/li>
&lt;li>
&lt;p>For proxy, if using rule-based proxy, need to note Netflix domains aren&amp;rsquo;t just one. Sharing Surge format proxy rules here, &lt;a href="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/release/rule/Surge/Netflix/Netflix.list" target="_blank" rel="noopener">for reference only&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="common-questions">
&lt;a class="heading-anchor-link" href="#common-questions">Common Questions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-questions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="what-determines-the-series-played">
&lt;a class="heading-anchor-link" href="#what-determines-the-series-played">What determines the series played&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-determines-the-series-played"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The IP address used when watching Netflix. If using Singapore region IP to watch Netflix, then Netflix series will be Singapore region series content, same for other regions.&lt;/p>
&lt;h3 id="which-region-has-most-content-sources">
&lt;a class="heading-anchor-link" href="#which-region-has-most-content-sources">Which region has most content sources&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="which-region-has-most-content-sources"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Singapore region has most Chinese content sources.&lt;/p>
&lt;h3 id="shows-incorrect-password">
&lt;a class="heading-anchor-link" href="#shows-incorrect-password">Shows incorrect password&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="shows-incorrect-password"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>99% of cases are because of your proxy node issues, because Netflix detects your IP during login, and only during login detection is slightly stricter: App &amp;gt; Web&lt;/p>
&lt;p>Solution: Close browser, then change proxy software node (or change region), re-enter web/App login.&lt;/p>
&lt;blockquote>
&lt;p>Web has lower node requirements. If App login fails, can try web login first. If web can login normally but App cannot, this definitely indicates node issues.&lt;/p>
&lt;/blockquote>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Used Netflix for several months now, feelings as follows&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Currently feel Netflix resources aren&amp;rsquo;t particularly abundant, like Marvel stuff definitely not available, but categories are comprehensive enough, sufficient for me&lt;/p>
&lt;/li>
&lt;li>
&lt;p>No ads etc., compared to all domestic video sites, much better&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Multi-subtitle/multi-language support is great, though specific depends on content source&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="related-documentation">
&lt;a class="heading-anchor-link" href="#related-documentation">Related Documentation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documentation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://netflixhz.com/sign-up-for-netflix/" target="_blank" rel="noopener">Most Cost-Effective Netflix Account Registration Method, This Article is Enough for China Netflix Subscription&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Getting the Dyson V8 Vacuum</title><link>https://en.1991421.cn/2023/09/29/bought-dyson-v8/</link><pubDate>Fri, 29 Sep 2023 08:50:54 +0800</pubDate><guid>https://en.1991421.cn/2023/09/29/bought-dyson-v8/</guid><description>&lt;blockquote>
&lt;p>I bought a Puppyoo D531 five years ago. For something that cost around 1,000 CNY, it&amp;rsquo;s served me well, and the battery life is still acceptable. The powered floor brush, however, keeps breaking.&lt;/p>
&lt;p>So this time I decided to switch to Dyson.&lt;/p>
&lt;/blockquote>
&lt;p>To keep costs under control, I went with the entry-level V8. Newer models like the V12 are only about 1,000 CNY more, but I wanted to stick to my budget—good enough is good enough. I grabbed the V8 from JD for &lt;code>1989 CNY&lt;/code>. After two weeks of use, here&amp;rsquo;s a quick rundown of the pros and cons.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-09-29-092604.jpeg"
alt="https://static.1991421.cn/2023/2023-09-29-092604.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Top-notch aesthetics&lt;/p>
&lt;p>Once unboxed, the vacuum looks fantastic. It&amp;rsquo;s mostly plastic, but still stylish, and it&amp;rsquo;s not heavy in the hand.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Great user experience&lt;/p>
&lt;ul>
&lt;li>Scan a QR code with WeChat on first use to register, watch tutorials, and manage warranty via the mini program. Learning how to use each attachment is quick.&lt;/li>
&lt;li>My old Puppyoo required removing the battery to charge; the Dyson just drops onto the docking station.&lt;/li>
&lt;li>Filters and heads are easy to detach and clean. Use a coin or flathead screwdriver to open the main head and a brush to clean it.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Useful attachments&lt;/p>
&lt;p>I barely used the Puppyoo accessories, but the Dyson attachments are genuinely effective. Swapping them is smoother, so I use them more often.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Solid suction&lt;/p>
&lt;p>Most importantly, the suction power is strong and the noise level is reasonable.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>You have to hold the power trigger the entire time, which also makes accidental presses more likely.&lt;/li>
&lt;li>Emptying the dust bin isn&amp;rsquo;t very clean—debris tends to stick.&lt;/li>
&lt;li>There&amp;rsquo;s no official no-drill charging stand.&lt;/li>
&lt;/ol>
&lt;p>Most of these drawbacks are reportedly addressed in newer models like the V12, so I&amp;rsquo;ll look at those when it&amp;rsquo;s time to upgrade again.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>For around 2,000 CNY, the Dyson V8 delivers exactly the experience I was hoping for—it looks cool and works well.&lt;/li>
&lt;li>The pain points I had with the Puppyoo are all resolved with the Dyson.&lt;/li>
&lt;/ol>
&lt;h2 id="related-resources">
&lt;a class="heading-anchor-link" href="#related-resources">Related Resources&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-resources"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/watch?v=ZTwUQlFa5js&amp;amp;ab_channel=%E6%96%B0%E8%A5%BF%E8%98%AD%C2%B7%E5%90%91%E5%BE%80%E7%9A%84%E7%94%9F%E6%B4%BBJohnny%26Nancy" target="_blank" rel="noopener">Routine Dyson V8 Cleaning&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Home Renovation Issues Record</title><link>https://en.1991421.cn/2023/09/12/dbf311a/</link><pubDate>Tue, 12 Sep 2023 22:46:21 +0800</pubDate><guid>https://en.1991421.cn/2023/09/12/dbf311a/</guid><description>&lt;h2 id="description">
&lt;a class="heading-anchor-link" href="#description">Description&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="description"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>First time dealing with this renovation company, also my first time renovating, this renovation does not include custom furniture.&lt;/p>
&lt;/blockquote>
&lt;h2 id="renovation-package">
&lt;a class="heading-anchor-link" href="#renovation-package">Renovation Package&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="renovation-package"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Cost around &lt;code>110,000 CNY&lt;/code>&lt;/p>
&lt;ul>
&lt;li>B3 package&lt;/li>
&lt;li>Additional items: Only tile grouting&lt;/li>
&lt;/ul>
&lt;h2 id="companys-official-marketing">
&lt;a class="heading-anchor-link" href="#companys-official-marketing">Company&amp;rsquo;s Official Marketing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="companys-official-marketing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Screenshot from recent Beijing subway ads&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/94a3165e-edea-4728-8f5a-8fe7f68be764"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="actual-issues">
&lt;a class="heading-anchor-link" href="#actual-issues">Actual Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="actual-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>From the start of renovation to now (0831 - one week after moving in), I&amp;rsquo;ve discovered the following issues. All are marked with final status.&lt;/p>
&lt;h3 id="1-grouting-worker-urinated-in-kitchen-violation---resolved">
&lt;a class="heading-anchor-link" href="#1-grouting-worker-urinated-in-kitchen-violation---resolved">1. Grouting worker urinated in kitchen, violation - Resolved&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="1-grouting-worker-urinated-in-kitchen-violation---resolved"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Reported to the company, went through official complaint process, eventually settled privately. Grouting company and the main company provided compensation and cleaning service. Of course there were some twists during this process. The lesson is that third-party services like grouting in renovation are very unreliable.&lt;/li>
&lt;li>Since this issue involved compensation resolution, I removed the original video online to avoid too much impact on the foreman.&lt;/li>
&lt;li>To avoid affecting appetite, I won&amp;rsquo;t post the original images/videos here.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/cd345af7-937b-4a37-bfe7-9fbd8c287ae6"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/b47714b6-c2f1-4d2d-bc8f-a6b99a9fec51"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="2-kitchen-tile-color-was-changed-during-process-but-designer-didnt-remind-that-grouting-color-also-needed-to-change-causing-significant-color-difference-in-kitchen---left-unresolved">
&lt;a class="heading-anchor-link" href="#2-kitchen-tile-color-was-changed-during-process-but-designer-didnt-remind-that-grouting-color-also-needed-to-change-causing-significant-color-difference-in-kitchen---left-unresolved">2. Kitchen tile color was changed during process, but designer didn&amp;rsquo;t remind that grouting color also needed to change, causing significant color difference in kitchen - Left unresolved&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2-kitchen-tile-color-was-changed-during-process-but-designer-didnt-remind-that-grouting-color-also-needed-to-change-causing-significant-color-difference-in-kitchen---left-unresolved"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>This issue was left unresolved because changing grouting would damage tiles.&lt;/p>
&lt;p>Screenshot shows current kitchen tile + grouting effect
&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/323d1272-d07e-4b99-99d4-3a1431a57f35"
alt="IMG_2798"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Screenshot shows bathroom tile + grouting effect&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/db4fd674-dd1f-4c0a-952d-61a872a1050e"
alt="IMG_2799"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>The direct cause of this issue was that I changed tile color, but as a non-professional, I didn&amp;rsquo;t think about changing grouting color accordingly. The designer, being more professional, didn&amp;rsquo;t remind me either, causing this major color difference issue. Had to accept it.&lt;/p>
&lt;h3 id="3-outlets-not-horizontally-aligned-some-angles-ridiculously-off---resolved">
&lt;a class="heading-anchor-link" href="#3-outlets-not-horizontally-aligned-some-angles-ridiculously-off---resolved">3. Outlets not horizontally aligned, some angles ridiculously off - Resolved&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="3-outlets-not-horizontally-aligned-some-angles-ridiculously-off---resolved"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Several were very crooked. I got a level and checked each one, finally had the worker go through and fix them all.&lt;/p>
&lt;p>The foreman&amp;rsquo;s explanation for this issue: Some outlets didn&amp;rsquo;t have level available during installation, so they weren&amp;rsquo;t done properly. 😮‍💨&lt;/p>
&lt;h3 id="4-company-promised-2-usb-port-outlets-not-installed---resolved">
&lt;a class="heading-anchor-link" href="#4-company-promised-2-usb-port-outlets-not-installed---resolved">4. Company promised 2 USB port outlets not installed - Resolved&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="4-company-promised-2-usb-port-outlets-not-installed---resolved"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Reported to designer/foreman, finally foreman compensated with 2 USB outlets. I found on JD there are two types with price difference of 20 vs 70 CNY, so if we don&amp;rsquo;t pay attention, it&amp;rsquo;s quite a rip-off. Foreman&amp;rsquo;s explanation was that if you don&amp;rsquo;t mention it, he won&amp;rsquo;t proactively buy and install these. But the absurd thing is that the company&amp;rsquo;s package clearly stated this.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/03604bc7-2875-4a47-87df-bbe4a3cdc35b"
alt="IMG_2485"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/a982de47-d6c7-4608-baec-c38a78d75a0e"
alt="IMG_2797"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="5-bathroom-vanity-includes-light-but-corresponding-electrical-handover-stage-didnt-leave-appropriate-outlet---resolved">
&lt;a class="heading-anchor-link" href="#5-bathroom-vanity-includes-light-but-corresponding-electrical-handover-stage-didnt-leave-appropriate-outlet---resolved">5. Bathroom vanity includes light, but corresponding electrical handover stage didn&amp;rsquo;t leave appropriate outlet - Resolved&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="5-bathroom-vanity-includes-light-but-corresponding-electrical-handover-stage-didnt-leave-appropriate-outlet---resolved"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Since no outlet was left, had to use the method shown below, but it&amp;rsquo;s dangerous and unsightly
&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/6da6decd-e9f9-416c-8e25-24aed461f34d"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>After negotiation, solution as shown in image 2
&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/65913e6b-9160-40f1-afbc-58832d6efa3d"
alt="IMG_2796"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="6-after-handover-completion-discovered-all-outlets-had-no-power">
&lt;a class="heading-anchor-link" href="#6-after-handover-completion-discovered-all-outlets-had-no-power">6. After handover completion, discovered all outlets had no power&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="6-after-handover-completion-discovered-all-outlets-had-no-power"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/a67dd141-77e8-4dff-a511-e7350a8c6196"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>This issue was extremely absurd and wasted my time. Finally resolved, it was due to weak current box issues.&lt;/p>
&lt;h3 id="7-after-handover-completion-first-use-revealed-bathroom-drain-blockage">
&lt;a class="heading-anchor-link" href="#7-after-handover-completion-first-use-revealed-bathroom-drain-blockage">7. After handover completion, first use revealed bathroom drain blockage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="7-after-handover-completion-first-use-revealed-bathroom-drain-blockage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/945a4d2b-de42-4784-b10e-2736ef626288"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="8-bathroom-shower-fixture-left-large-gap-but-wasnt-informed">
&lt;a class="heading-anchor-link" href="#8-bathroom-shower-fixture-left-large-gap-but-wasnt-informed">8. Bathroom shower fixture left large gap, but wasn&amp;rsquo;t informed&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="8-bathroom-shower-fixture-left-large-gap-but-wasnt-informed"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I personally used air conditioning putty to fill the gap, didn&amp;rsquo;t report this upward.&lt;/p>
&lt;h3 id="9-washbasin-faucet-hotcold-connections-reversed">
&lt;a class="heading-anchor-link" href="#9-washbasin-faucet-hotcold-connections-reversed">9. Washbasin faucet hot/cold connections reversed&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="9-washbasin-faucet-hotcold-connections-reversed"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/b4dede77-6d83-49c8-9e89-d6d629f3f48d"
alt="IMG_2770"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://github.com/alanhe421/others-note/assets/9245110/98e37202-aca2-48d9-8fbe-a01f336f0bcf"
alt="IMG_2771"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Finally had worker come fix this by reversing the washbasin drain pipes.&lt;/p>
&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Of course these issues don&amp;rsquo;t represent that other brands/teams won&amp;rsquo;t have these problems, this is just a record. My impression of this company is that at least it doesn&amp;rsquo;t match their advertising promises.&lt;/li>
&lt;li>Currently it&amp;rsquo;s still okay, just don&amp;rsquo;t do their add-ons and renovation needs close supervision.&lt;/li>
&lt;/ol></description></item><item><title>NPS Explained (Simple Guide)</title><link>https://en.1991421.cn/2023/09/04/nps-intro/</link><pubDate>Mon, 04 Sep 2023 22:55:58 +0800</pubDate><guid>https://en.1991421.cn/2023/09/04/nps-intro/</guid><description>&lt;blockquote>
&lt;p>We integrated NPS into our web product a while back, but I hadn&amp;rsquo;t studied it systematically. I read up on it and summarized here.&lt;/p>
&lt;p>At the same time, I also used NPS to analyze the current product and clarify some of the deficiencies reflected by user feedback. I will work hard to improve it.&lt;/p>
&lt;/blockquote>
&lt;h2 id="nps">
&lt;a class="heading-anchor-link" href="#nps">NPS&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="nps"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>NPS stands for Net Promoter Score — a metric of how likely users are to recommend a brand/product/service.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-09-04-230253.jpeg"
alt="https://static.1991421.cn/2023/2023-09-04-230253.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="formula">
&lt;a class="heading-anchor-link" href="#formula">Formula&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="formula"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>NPS = (Promoters / Total) × 100% − (Detractors / Total) × 100%&lt;/p>
&lt;h3 id="examples">
&lt;a class="heading-anchor-link" href="#examples">Examples&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="examples"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>If 100 users participate in the survey, 80 recommend and 20 detract, then the NPS value is&lt;/p>
&lt;p>80% - 20% = 60%&lt;/p>
&lt;p>If 100 users participate in the survey, 20 recommend and 80 detract, then the NPS value is&lt;/p>
&lt;p>20% - 80% = -60%&lt;/p>
&lt;p>If 100 users participate in the survey, 20 recommend, 40 detract, and 40 are neutral, then the NPS value is&lt;/p>
&lt;p>20% - 40% = -20%&lt;/p>
&lt;h3 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Users give 0–10 ratings, but NPS ranges from −100% to +100%. Seeing 80 or 100 in charts is normal because it&amp;rsquo;s a percentage.&lt;/li>
&lt;li>The 9 vs. 10 distinction doesn&amp;rsquo;t matter to NPS — both are Promoters.&lt;/li>
&lt;/ol>
&lt;h2 id="our-product-right-now">
&lt;a class="heading-anchor-link" href="#our-product-right-now">Our product right now&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="our-product-right-now"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Our NPS hovers around 10 — positive, but with lots of room to improve. Only about 10% likelihood of recommendation.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>NPS is useful to surface user feedback via surveys. Listen and fix issues; next goal: reach 40%.&lt;/p>
&lt;h2 id="related-documents">
&lt;a class="heading-anchor-link" href="#related-documents">Related Documents&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documents"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.zcool.com.cn/article/ZMTIxMDI5Ng==.html" target="_blank" rel="noopener">Data Metrics Designers Must Understand — NPS&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>CLI Flags: -v, -V, and --v</title><link>https://en.1991421.cn/2023/08/14/58edec0/</link><pubDate>Mon, 14 Aug 2023 22:49:19 +0800</pubDate><guid>https://en.1991421.cn/2023/08/14/58edec0/</guid><description>&lt;blockquote>
&lt;p>I’ve been studying CLI tools and keep seeing different flag styles. Here’s what I’ve learned about conventions and differences.&lt;/p>
&lt;/blockquote>
&lt;h2 id="command-structure">
&lt;a class="heading-anchor-link" href="#command-structure">Command structure&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="command-structure"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>First, a common command structure:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://fig.io/docAssets/autocomplete/handbook/cli_structure.png"
alt="cli_structure"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>A few more points:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Some commands have both short and long formats for options. In the figure, &lt;code>b&lt;/code> doesn&amp;rsquo;t have a corresponding long format, but &lt;code>f&lt;/code> has both &lt;code>-f&lt;/code> and &lt;code>--force&lt;/code>. Short and long parameters have the same effect; they&amp;rsquo;re just different ways of writing.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Short flags can often be combined, but not always. For example, &lt;code>git checkout -b newBranch -f&lt;/code> cannot be combined into &lt;code>git checkout -bf newBranch&lt;/code>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Flags are case‑sensitive; some commands use uppercase flags.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Flags may take values using a space or &lt;code>=&lt;/code> depending on the CLI. Docker supports both: &lt;code>--name=&amp;quot;doc-searcher&amp;quot;&lt;/code> equals &lt;code>--name &amp;quot;doc-searcher&amp;quot;&lt;/code>.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="-v--v---v">
&lt;a class="heading-anchor-link" href="#-v--v---v">-v, -V, &amp;ndash;v&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="-v--v---v"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>With the structure in mind:&lt;/p>
&lt;ul>
&lt;li>&lt;code>-v&lt;/code> is a short flag.&lt;/li>
&lt;li>&lt;code>--v&lt;/code> is a long flag (though uncommon — most tools use names like &lt;code>--version&lt;/code>).&lt;/li>
&lt;li>&lt;code>-V&lt;/code> is a short flag using uppercase.&lt;/li>
&lt;/ul>
&lt;h2 id="recommendations">
&lt;a class="heading-anchor-link" href="#recommendations">Recommendations&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="recommendations"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Different tools vary, which adds learning cost. When building your own CLI, follow common conventions. See &lt;a href="https://github.com/tj/commander.js" target="_blank" rel="noopener">commander.js&lt;/a> for a well‑adopted model.&lt;/p>
&lt;ol>
&lt;li>Use spaces to separate parameter values&lt;/li>
&lt;li>Use both short and long formats: short format as a single character, long format as a complete word&lt;/li>
&lt;li>Use lowercase for subcommands/parameters&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Following CLI conventions improves efficiency and avoids mistakes.&lt;/li>
&lt;li>Good CLI design lowers the learning curve.&lt;/li>
&lt;/ol></description></item><item><title>Kubernetes Quick Start: Step-by-Step Guide</title><link>https://en.1991421.cn/2023/08/06/kubernetes/</link><pubDate>Sun, 06 Aug 2023 23:07:48 +0800</pubDate><guid>https://en.1991421.cn/2023/08/06/kubernetes/</guid><description>&lt;blockquote>
&lt;p>I recently needed to learn Kubernetes for work, so I recorded some common operations here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;em>Note: Images are from the web.&lt;/em>&lt;/p>
&lt;h2 id="terms">
&lt;a class="heading-anchor-link" href="#terms">Terms&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="terms"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>k8s&lt;/p>
&lt;p>Kubernetes, similar to how internationalization is abbreviated to i18n.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Ingress
Manages HTTP/HTTPS routes from outside the cluster to internal services.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-08-06-231900.jpeg"
alt="https://static.1991421.cn/2023/2023-08-06-231900.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="common-commands">
&lt;a class="heading-anchor-link" href="#common-commands">Common commands&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-commands"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Install on Mac&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew install kubectl
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Upgrade CLI on Mac&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew upgrade kubectl
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Version&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">kubectl version
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Connect to Kubernetes cluster with kubectl&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">KUBECONFIG&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nv">$KUBECONFIG&lt;/span>:&lt;span class="nv">$HOME&lt;/span>/Downloads/cls-xxxx-config
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">kubectl config --kubeconfig&lt;span class="o">=&lt;/span>&lt;span class="nv">$HOME&lt;/span>/Downloads/cls-xxxx-config get-contexts
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">kubectl config --kubeconfig&lt;span class="o">=&lt;/span>&lt;span class="nv">$HOME&lt;/span>/Downloads/cls-xxxx-config use-context cls-xxxx-xxxx-context-default
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># View cluster&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">kubectl get pods -n kube-system
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">## Download files&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">kubectl &lt;span class="nb">exec&lt;/span> -i &lt;span class="o">[&lt;/span>containerId&lt;span class="o">]&lt;/span> -- tar -cpf - -C &lt;span class="s1">&amp;#39;/apiserver-proxy&amp;#39;&lt;/span> &lt;span class="s1">&amp;#39;cert.pem&amp;#39;&lt;/span> &amp;gt; download.tar
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">## Upload&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> tar -cf &lt;span class="s1">&amp;#39;/Users/alanhe/Desktop/csr (1).tar&amp;#39;&lt;/span> &lt;span class="s1">&amp;#39;/Users/alanhe/Desktop/csr (1).pem&amp;#39;&lt;/span> &lt;span class="p">|&lt;/span> kubectl &lt;span class="nb">exec&lt;/span> -i kubernetes-proxy-884c9c6c9-vkgtg -- tar -xf - -C &lt;span class="s1">&amp;#39;/apiserver-proxy/csr (1).tar&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="image-push">
&lt;a class="heading-anchor-link" href="#image-push">Image push&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="image-push"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Before deployment, the image must be pushed to the target registry.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">docker build -t centos-lrzsz:latest .
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">docker tag centos-lrzsz:latest xxx.com/ai/xxx:xx
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Login to registry&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">docker login
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Push&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">docker push xxx.com/ai/xxx:xx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://time.geekbang.org/column/intro/100114501" target="_blank" rel="noopener">https://time.geekbang.org/column/intro/100114501&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://cloud.tencent.com/document/product/457/32187" target="_blank" rel="noopener">https://cloud.tencent.com/document/product/457/32187&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/#install-with-homebrew-on-macos" target="_blank" rel="noopener">https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/#install-with-homebrew-on-macos&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Bought a NIU Electric Scooter (MQiL)</title><link>https://en.1991421.cn/2023/07/25/bought-niu-ebike/</link><pubDate>Tue, 25 Jul 2023 23:36:02 +0800</pubDate><guid>https://en.1991421.cn/2023/07/25/bought-niu-ebike/</guid><description>&lt;blockquote>
&lt;p>After trying Segway-Ninebot and NIU models both online and in stores, I went with the NIU MQiL Urban. I picked it up on the 15th; nearly two weeks later I&amp;rsquo;m still satisfied overall. Here are my notes.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-05-20-000226.jpeg"
alt="https://static.1991421.cn/2024/2024-05-20-000226.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="brand-considerations">
&lt;a class="heading-anchor-link" href="#brand-considerations">Brand Considerations&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="brand-considerations"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I&amp;rsquo;m picky about user experience. Within my budget and spec requirements, the shortlist came down to Ninebot and NIU. Ninebot&amp;rsquo;s design didn&amp;rsquo;t appeal to me, and I saw a lot of posts about minor issues, so I chose NIU.&lt;/p>
&lt;h2 id="configuration">
&lt;a class="heading-anchor-link" href="#configuration">Configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="configuration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>To stay within budget, I picked the MQiL Urban priced at &lt;code>¥4999&lt;/code>. Due to mandatory bundles, the final price was &lt;code>¥5699&lt;/code>.&lt;/p>
&lt;h3 id="bundle-included">
&lt;a class="heading-anchor-link" href="#bundle-included">Bundle Included&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bundle-included"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Rearview mirrors&lt;/li>
&lt;li>Rear seat&lt;/li>
&lt;/ol>
&lt;h3 id="add-ons">
&lt;a class="heading-anchor-link" href="#add-ons">Add-ons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="add-ons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Upgraded to a wider rear seat for &lt;code>75 CNY&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>No other extras so far.&lt;/p>
&lt;h3 id="beijing-dealer-shenanigans">
&lt;a class="heading-anchor-link" href="#beijing-dealer-shenanigans">Beijing Dealer Shenanigans&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="beijing-dealer-shenanigans"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The dealer forced bundles (only for this model). I filed a complaint but didn&amp;rsquo;t get anywhere.&lt;/p>
&lt;p>Details: &lt;a href="https://www.v2ex.com/t/956842" target="_blank" rel="noopener">https://www.v2ex.com/t/956842&lt;/a>&lt;/p>
&lt;h2 id="usage-notes">
&lt;a class="heading-anchor-link" href="#usage-notes">Usage Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage-notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>The NIU app is pretty good, though the pop-up ads are annoying—standard behavior for domestic apps. I&amp;rsquo;ll see if a proxy rule can block them.&lt;/li>
&lt;li>The scooter looks great; the design is instantly recognizable.&lt;/li>
&lt;li>I love the keyless start—no more carrying keys—but it does make me worry about my phone dying.&lt;/li>
&lt;li>There&amp;rsquo;s a onboard &lt;code>USB-C&lt;/code> port, so you can trickle charge your phone.&lt;/li>
&lt;li>Supports Apple Watch NFC unlocking.
&lt;ul>
&lt;li>Official tutorial: &lt;a href="https://www.bilibili.com/video/BV1Zz4y1H7a5/?vd_source=1d8b05f95c6e1516ec9abafb41178423" target="_blank" rel="noopener">Learn to unlock the NIU MQiL with Apple Watch NFC in one minute&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="gb-speed-limit">
&lt;a class="heading-anchor-link" href="#gb-speed-limit">GB Speed Limit&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="gb-speed-limit"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>The &lt;code>25 km/h&lt;/code> cap can be lifted—just ask the shop.&lt;/li>
&lt;li>The beeping above 15 km/h can usually be disabled at the same time.&lt;/li>
&lt;/ol>
&lt;h2 id="third-party-accessories">
&lt;a class="heading-anchor-link" href="#third-party-accessories">Third-Party Accessories&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="third-party-accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Dashboard protector film&lt;/li>
&lt;li>Metal footpeg end caps&lt;/li>
&lt;li>Extended kickstand base / widening pad&lt;/li>
&lt;li>Xiaomi portable inflator&lt;/li>
&lt;/ul>
&lt;p>I bought most of these on Pinduoduo because the prices are lower.&lt;/p>
&lt;h2 id="ruizhi-vip">
&lt;a class="heading-anchor-link" href="#ruizhi-vip">RuiZhi VIP&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ruizhi-vip"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I recommend keeping the subscription—the features are essential, and a 3-year plan is cheaper overall.&lt;/p>
&lt;img src="https://static.1991421.cn/2024/2024-06-15-233128.jpeg" alt="https://static.1991421.cn/2024/2024-06-15-233128.jpeg" style="zoom:50%;" />
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Overall, I&amp;rsquo;m pleased with the NIU so far.&lt;/p></description></item><item><title>Getting Started with Jupyter</title><link>https://en.1991421.cn/2023/07/23/jupyter/</link><pubDate>Sun, 23 Jul 2023 16:09:47 +0800</pubDate><guid>https://en.1991421.cn/2023/07/23/jupyter/</guid><description>&lt;blockquote>
&lt;p>Jupyter Notebook is a web-based application for interactive computing. It can be used across the full workflow: development, documentation, execution, and result display.&lt;/p>
&lt;/blockquote>
&lt;h2 id="positioning">
&lt;a class="heading-anchor-link" href="#positioning">Positioning&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="positioning"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Scientific computing
&lt;ul>
&lt;li>&lt;a href="https://www.jetbrains.com/help/idea/scientific-tools.html" target="_blank" rel="noopener">https://www.jetbrains.com/help/idea/scientific-tools.html&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="installation">
&lt;a class="heading-anchor-link" href="#installation">Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl"># python require
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># install
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install notebook
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># Chinese language pack
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install jupyterlab-language-pack-zh-CN
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># start
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">jupyter notebook --allow-root --ip 0.0.0.0 --port 8888
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">jupyter server list
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># run in background
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nohup jupyter notebook --allow-root --ip 0.0.0.0 --port 8888 &amp;amp;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># version
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">jupyter --version
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="product-forms">
&lt;a class="heading-anchor-link" href="#product-forms">Product forms&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="product-forms"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="server-web">
&lt;a class="heading-anchor-link" href="#server-web">Server (Web)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="server-web"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;a href="https://github.com/jupyter/notebook" target="_blank" rel="noopener">https://github.com/jupyter/notebook&lt;/a>&lt;/p>
&lt;h3 id="lite-version---runs-fully-in-the-browser">
&lt;a class="heading-anchor-link" href="#lite-version---runs-fully-in-the-browser">Lite version - runs fully in the browser&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="lite-version---runs-fully-in-the-browser"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;a href="https://github.com/jupyterlite/jupyterlite" target="_blank" rel="noopener">jupyterlite&lt;/a>&lt;/p>
&lt;p>demo: &lt;a href="https://jupyterlite.readthedocs.io/en/latest/_static/lab/index.html" target="_blank" rel="noopener">https://jupyterlite.readthedocs.io/en/latest/_static/lab/index.html&lt;/a>&lt;/p>
&lt;h3 id="plugin-version">
&lt;a class="heading-anchor-link" href="#plugin-version">Plugin version&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="plugin-version"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;a href="https://github.com/Microsoft/vscode-jupyter" target="_blank" rel="noopener">https://github.com/Microsoft/vscode-jupyter&lt;/a>&lt;/p>
&lt;h2 id="customization">
&lt;a class="heading-anchor-link" href="#customization">Customization&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="customization"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Internationalization
&lt;ul>
&lt;li>install language pack as above&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Plugins and extensions&lt;/li>
&lt;/ul>
&lt;h2 id="other">
&lt;a class="heading-anchor-link" href="#other">Other&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>The terminal in Jupyter uses xtermjs + codemirror&lt;/li>
&lt;/ol>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://docs.jupyter.org/en/latest/running.html" target="_blank" rel="noopener">https://docs.jupyter.org/en/latest/running.html&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/jupyter/jupyter/wiki/Jupyter-kernels" target="_blank" rel="noopener">https://github.com/jupyter/jupyter/wiki/Jupyter-kernels&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.zhihu.com/question/37490497/answer/2037383389" target="_blank" rel="noopener">https://www.zhihu.com/question/37490497/answer/2037383389&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.zhihu.com/topic/20064574/hot" target="_blank" rel="noopener">https://www.zhihu.com/topic/20064574/hot&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Bought an AirTag</title><link>https://en.1991421.cn/2023/06/18/airtag/</link><pubDate>Sun, 18 Jun 2023 16:26:55 +0800</pubDate><guid>https://en.1991421.cn/2023/06/18/airtag/</guid><description>&lt;blockquote>
&lt;p>Recently bought an AirTag on JD.com for 178 CNY. Played with it and thought it was quite interesting. Here&amp;rsquo;s a summary.&lt;/p>
&lt;/blockquote>
&lt;img src="https://static.1991421.cn/2023/2023-06-18-170703.PNG" alt="https://static.1991421.cn/2023/2023-06-18-170703.PNG" style="zoom:33%;" />
&lt;h2 id="update">
&lt;a class="heading-anchor-link" href="#update">Update&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="update"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As of now, I&amp;rsquo;ve bought 2 AirTags.&lt;/p>
&lt;h2 id="basics">
&lt;a class="heading-anchor-link" href="#basics">Basics&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="basics"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>AirTag was released in 2021, and after 2 years, the price remains firm. Initially, you could get one for around 100 CNY on Pinduoduo, but now it&amp;rsquo;s almost 200 CNY per unit. Apple products indeed retain their value well.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Battery life is approximately 1 year, which is sufficient, and replacing the battery is relatively simple.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>AirTag&amp;rsquo;s function is to track items using Find My.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Since AirTag doesn&amp;rsquo;t come with a protective case and official ones are expensive, I recommend buying third-party protective cases to prevent loss and scratches.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="use-cases">
&lt;a class="heading-anchor-link" href="#use-cases">Use cases&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="use-cases"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I only bought one for now, so I put it on my keychain. The scenario it solves is when I&amp;rsquo;m in a hurry to go out and can&amp;rsquo;t find my keys but am sure they&amp;rsquo;re not lost. With AirTag, it&amp;rsquo;s much better—I can locate them and make it emit a sound.&lt;/p>
&lt;p>I&amp;rsquo;m considering using it for a while longer, and if it&amp;rsquo;s good, I might buy a few more to put on items like my backpack and suitcase.&lt;/p>
&lt;h2 id="impressions">
&lt;a class="heading-anchor-link" href="#impressions">Impressions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="impressions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>The build quality is excellent, as expected from Apple.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The positioning capability, especially indoor positioning, isn&amp;rsquo;t very accurate, but most of the time, distance estimation + sound can solve the problem.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="fun-use--shortcuts--nfc">
&lt;a class="heading-anchor-link" href="#fun-use--shortcuts--nfc">Fun use — Shortcuts + NFC&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="fun-use--shortcuts--nfc"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>AirTag can be used as an NFC tag in iPhone&amp;rsquo;s Shortcuts for automation. For example, &lt;a href="https://youtu.be/wwbIVI3-PhY?t=768" target="_blank" rel="noopener">tracking water drinking status&lt;/a> — touch once to record.&lt;/p>
&lt;p>I don&amp;rsquo;t have this kind of need currently; it&amp;rsquo;s more of an exploration of usage possibilities.&lt;/p>
&lt;h2 id="cheaper-alternatives">
&lt;a class="heading-anchor-link" href="#cheaper-alternatives">Cheaper alternatives?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cheaper-alternatives"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For budget considerations, I tried buying a cheaper alternative, but found it to be a fake alternative in practical use. The most critical flaw is that AirTag can use any nearby Apple device to send location information, while cheaper alternatives can only communicate location information with the bound device. For example, if the bound iPhone is separated from the tag, you will always see the location where they were separated, so the most crucial location information becomes invalid. Therefore, cheaper alternatives are not recommended.&lt;/p>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>The advantages of AirTag lie in its accurate tracking ability, seamless integration with Apple ecosystem, and strong privacy protection features.&lt;/li>
&lt;li>Apple ecosystem users, especially those who are forgetful and often can&amp;rsquo;t find their keys, are more recommended to buy. The fact that the price remains so firm 2 years after launch also indicates its value to some extent.&lt;/li>
&lt;/ol></description></item><item><title>Purchasing AirPods 3</title><link>https://en.1991421.cn/2023/06/02/airpods3/</link><pubDate>Fri, 02 Jun 2023 23:15:06 +0800</pubDate><guid>https://en.1991421.cn/2023/06/02/airpods3/</guid><description>&lt;blockquote>
&lt;p>From June 2020 to now, 3 years later, my AirPods 2 couldn&amp;rsquo;t keep up anymore, so I upgraded to the 3rd generation during the 618 sale. I continued with JD, chose the MagSafe version, purchase price &lt;code>1179CNY&lt;/code>.&lt;/p>
&lt;p>After using the 3rd generation for 2 days, the overall feeling is below expectations, hoping to gradually adapt. Here I&amp;rsquo;ll list the pros and cons I personally discovered.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-06-02-234622.jpeg"
alt="https://static.1991421.cn/2023/2023-06-02-234622.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="3rd-generation-vs-2nd-generation">
&lt;a class="heading-anchor-link" href="#3rd-generation-vs-2nd-generation">3rd Generation vs 2nd Generation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="3rd-generation-vs-2nd-generation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="disadvantages">
&lt;a class="heading-anchor-link" href="#disadvantages">Disadvantages&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="disadvantages"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>Comfort&lt;/p>
&lt;p>Mainly because the 1st and 2nd generations share the same design, and after years of getting used to them, currently wearing the 3rd generation causes some discomfort, mainly feeling tighter. Of course, the benefit is that they&amp;rsquo;re less likely to fall out. Overall, currently feel the comfort is not as good as the 2nd generation.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Charging Case Earphone Slot&lt;/p>
&lt;p>Still influenced by the first two generations, the earphone insertion direction is exactly opposite to before, causing each insertion to take a bit longer than before.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-06-02-234254.jpeg"
alt="https://static.1991421.cn/2023/2023-06-02-234254.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="advantages">
&lt;a class="heading-anchor-link" href="#advantages">Advantages&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="advantages"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>Wireless Charging&lt;/p>
&lt;p>Currently not being used, mainly because I don&amp;rsquo;t have a car yet, but better to have it than not&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Increased Battery Life&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="controversial-points">
&lt;a class="heading-anchor-link" href="#controversial-points">Controversial Points&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="controversial-points"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>Operation Experience&lt;/p>
&lt;p>For example, to activate Siri besides voice activation, manual activation requires pressing the earphone - successful press gives audio feedback, so normally two fingers would be needed. Whereas before, just tapping with one finger was enough. Playing music, pausing music, hanging up calls are the same, same experience.&lt;/p>
&lt;p>The operation is a bit more troublesome, but the benefit is that previous tapping was easy to get the force wrong and cause the earphones to fall out. So this has both advantages and disadvantages.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-06-02-234946.jpeg"
alt="https://static.1991421.cn/2023/2023-06-02-234946.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="summary">
&lt;a class="heading-anchor-link" href="#summary">Summary&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="summary"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Personally, I&amp;rsquo;ve used from the 1st generation to the current 3rd generation. The current 3rd generation has less experience than the previous 2nd generation and has these disadvantages, but it&amp;rsquo;s still a capable product. Paired with other Apple devices, I genuinely like this ecosystem experience.&lt;/p>
&lt;p>So, I still recommend everyone to try it.&lt;/p></description></item><item><title>Unofficial AirPods 2 Battery Replacement</title><link>https://en.1991421.cn/2023/04/05/airpods2/</link><pubDate>Wed, 05 Apr 2023 10:29:22 +0800</pubDate><guid>https://en.1991421.cn/2023/04/05/airpods2/</guid><description>&lt;blockquote>
&lt;p>I purchased AirPods 2 in May 2020, and after nearly 3 years, the earbuds became unstable, mainly showing occasional connection failures/disconnections, and the earbuds themselves weren&amp;rsquo;t very durable. To avoid affecting usage, I decided to fix this.&lt;/p>
&lt;/blockquote>
&lt;ul>
&lt;li>
&lt;p>Option 1: Trade-in through JD and get a new pair, valued at &lt;code>200+ CNY&lt;/code>. AirPods 1 had the same trade-in value back then. Plus, AirPods 3 are still quite expensive at &lt;code>1K+ CNY&lt;/code>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Option 2: Replace the battery 🔋&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>In the spirit of frugality, I decided to try unofficial battery replacement.&lt;/p>
&lt;h2 id="update">
&lt;a class="heading-anchor-link" href="#update">Update⚠️&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="update"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After using the battery-replaced AirPods for several months, I found the battery became very unreliable, and the earbuds&amp;rsquo; connection sensitivity decreased. So I no longer recommend this approach.&lt;/p>
&lt;h2 id="downsides-of-unofficial-repair">
&lt;a class="heading-anchor-link" href="#downsides-of-unofficial-repair">Downsides of Unofficial Repair&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="downsides-of-unofficial-repair"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Before repair, you should know that once you go through unofficial repair, you can no longer use Apple&amp;rsquo;s official after-sales service or trade-in programs, except selling on second-hand platforms like Xianyu.&lt;/p>
&lt;h2 id="process">
&lt;a class="heading-anchor-link" href="#process">Process&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="process"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I used a shop recommended on V2EX, link below:&lt;/p>
&lt;blockquote>
&lt;p>[Taobao] &lt;a href="https://m.tb.cn/h.UrtpzaT?tk=iHRSdkm6Xb2" target="_blank" rel="noopener">https://m.tb.cn/h.UrtpzaT?tk=iHRSdkm6Xb2&lt;/a> CZ3457 (AirPods battery replacement service)
Click the link to open directly or search directly on Taobao&lt;/p>
&lt;/blockquote>
&lt;p>Repair content: &lt;code>Both earbud batteries&lt;/code>&lt;/p>
&lt;p>Price: &lt;code>75 CNY&lt;/code>&lt;/p>
&lt;p>I mailed the entire set including the charging case. The shop also helped clean it.&lt;/p>
&lt;h3 id="interlude">
&lt;a class="heading-anchor-link" href="#interlude">Interlude&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="interlude"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I had repairs done twice.&lt;/p>
&lt;ul>
&lt;li>After the first repair, I found the left earbud&amp;rsquo;s microphone had issues - it would make strange noises during calls, which was scary and made me worry about explosion. After communicating with the shop, they agreed to re-repair at their expense for shipping costs.&lt;/li>
&lt;li>After receiving it the second time, I found no issues during use.&lt;/li>
&lt;/ul>
&lt;h2 id="after-repair">
&lt;a class="heading-anchor-link" href="#after-repair">After Repair&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="after-repair"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Previous issues like battery life and unstable connections were significantly improved. I felt it could last another year or so.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>If money isn&amp;rsquo;t tight, I&amp;rsquo;d recommend against third-party repairs&lt;/li>
&lt;li>Given that this repair still required a second attempt, I&amp;rsquo;m somewhat uneasy about third-party repairs for Apple&amp;rsquo;s small precision devices. So next time I probably won&amp;rsquo;t go with repairs - this was more of an experience for me.&lt;/li>
&lt;/ol></description></item><item><title>Registering a Marriage in Beijing</title><link>https://en.1991421.cn/2023/03/11/f5f1705/</link><pubDate>Sat, 11 Mar 2023 19:46:38 +0800</pubDate><guid>https://en.1991421.cn/2023/03/11/f5f1705/</guid><description>&lt;blockquote>
&lt;p>Today I went to register for marriage, which marks a new era for me.&lt;/p>
&lt;p>Here I also summarize the marriage registration process in Beijing. Because my situation is special—one party has a Beijing collective hukou and the other has an out-of-town collective hukou—I was worried about document issues, but everything went smoothly in the end. I summarize this here in case it helps some friends.&lt;/p>
&lt;/blockquote>
&lt;!-- more -->
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-03-11-200853.jpeg"
alt="https://static.1991421.cn/2023/2023-03-11-200853.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="requirements">
&lt;a class="heading-anchor-link" href="#requirements">Requirements&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="requirements"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>To get married in Beijing, at least one party must have a Beijing hukou. The exception is if you are from Hong Kong, Macao, or Taiwan—you can also register.&lt;/li>
&lt;li>If you have a Beijing collective hukou, you must register in the corresponding district. I have a Haidian collective hukou, so I chose Haidian District for registration.&lt;/li>
&lt;/ul>
&lt;h2 id="appointment">
&lt;a class="heading-anchor-link" href="#appointment">Appointment&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="appointment"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Search for &amp;ldquo;marriage registration&amp;rdquo; on WeChat, enter Beijing Government Services, and select &amp;ldquo;Marriage Registration Appointment&amp;rdquo;.&lt;/li>
&lt;li>You will receive SMS reminders when your appointment is successful and as the appointment date approaches.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-03-11-200653.jpeg"
alt="https://static.1991421.cn/2023/2023-03-11-200653.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="documents-to-bring">
&lt;a class="heading-anchor-link" href="#documents-to-bring">Documents to bring&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="documents-to-bring"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Original ID cards of both parties&lt;/li>
&lt;li>Personal hukou page
&lt;ul>
&lt;li>For Beijing collective hukou: Provide the blue permanent resident registration card and a copy of the collective hukou front page. If you don&amp;rsquo;t have a hukou page, you need to apply for one at the talent center.&lt;/li>
&lt;li>For out-of-town collective hukou: Provide corresponding documents, such as the original permanent resident registration form.&lt;/li>
&lt;li>For non-collective hukou: Provide the original household registration book.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Marriage photos
&lt;ul>
&lt;li>2 photos with red background, white shirts, etc.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>If you are worried about document issues, be sure to go to the registration office in advance to ask. I couldn&amp;rsquo;t get through to the phone number provided online, so I went to the civil affairs bureau in person.&lt;/p>
&lt;p>The marriage registration location in Haidian is the &lt;strong>Civil Affairs Bureau Marriage Registration Sub-center of Haidian District Government Services&lt;/strong>.&lt;/p>
&lt;h2 id="registration">
&lt;a class="heading-anchor-link" href="#registration">Registration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="registration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>On the appointed date, bring all complete documents to register. The process is very fast—just confirm the information, sign, press your fingerprint, and you can leave.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Marriage is the formal step to start a family, so I will work hard.&lt;/p></description></item><item><title>How to Use AList (Step-by-Step Guide)</title><link>https://en.1991421.cn/2023/02/04/alist/</link><pubDate>Sat, 04 Feb 2023 11:57:12 +0800</pubDate><guid>https://en.1991421.cn/2023/02/04/alist/</guid><description>&lt;blockquote>
&lt;p>The alist-infuse-atv combination is fantastic, here&amp;rsquo;s a summary&lt;/p>
&lt;/blockquote>
&lt;h2 id="alist-installation">
&lt;a class="heading-anchor-link" href="#alist-installation">AList Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="alist-installation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Aliyun Drive has been very popular recently, and alist deserves part of the credit. AList aggregates cloud storage resources and exposes WebDAV services or can be used for online viewing directly.&lt;/p>
&lt;p>I recently deployed it on an Oracle Cloud server so it can be accessed from the internet.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Official script installation, note that account password will be printed after startup&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">curl -fsSL &lt;span class="s2">&amp;#34;https://alist.nn.ci/v3.sh&amp;#34;&lt;/span> &lt;span class="p">|&lt;/span> bash -s install
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Start service&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">systemctl start alist
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Update, password won&amp;#39;t be modified&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">curl -fsSL &lt;span class="s2">&amp;#34;https://alist.nn.ci/v3.sh&amp;#34;&lt;/span> &lt;span class="p">|&lt;/span> bash -s update
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Official documentation 👉&lt;a href="https://alist.nn.ci/zh/guide/install/script.html" target="_blank" rel="noopener">here&lt;/a>&lt;/p>
&lt;h3 id="auto-update">
&lt;a class="heading-anchor-link" href="#auto-update">Auto Update&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="auto-update"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Manually configure a cron job to execute updates at scheduled times&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Execute daily at 6 AM, use crontab -e and press Enter to open editor&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">0&lt;/span> &lt;span class="m">6&lt;/span> * * * curl -fsSL &lt;span class="s2">&amp;#34;https://alist.nn.ci/v3.sh&amp;#34;&lt;/span> &lt;span class="p">|&lt;/span> bash -s update
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="https">
&lt;a class="heading-anchor-link" href="#https">HTTPS&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="https"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>For internet-deployed alist, if possible, it&amp;rsquo;s recommended to use HTTPS with a domain name. I recommend Caddy because it automatically applies for free certificates based on configured domains by default, ready to use out of the box&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">yum install yum-plugin-copr
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yum copr &lt;span class="nb">enable&lt;/span> @caddy/caddy
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yum install caddy
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>Caddyfile&lt;/code> configuration is as follows&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">alist.xx.xxx
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">reverse_proxy :5244
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="common-alist-configurations">
&lt;a class="heading-anchor-link" href="#common-alist-configurations">Common AList Configurations&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-alist-configurations"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Don&amp;rsquo;t deny guest user access&lt;/p>
&lt;p>Create an empty storage directory, such as /404, and set the guest user&amp;rsquo;s base path to /404 in the user settings&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>​ &lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-02-04-120626.jpeg"
alt="https://static.1991421.cn/2023/2023-02-04-120626.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;img src="https://static.1991421.cn/2023/2023-02-04-120707.jpeg" alt="https://static.1991421.cn/2023/2023-02-04-120707.jpeg" style="zoom:67%;" />
&lt;ol start="2">
&lt;li>
&lt;p>Index&lt;/p>
&lt;p>If you want search functionality on the web version, it&amp;rsquo;s recommended to enable indexing. The URL path is &lt;code>/@manage/indexes&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Enable GitHub single sign-on support&lt;/p>
&lt;/li>
&lt;/ol>
&lt;img src="https://static.1991421.cn/2023/2023-06-10-112917.jpeg" alt="https://static.1991421.cn/2023/2023-06-10-112917.jpeg" style="zoom:67%;" />
&lt;h2 id="usage">
&lt;a class="heading-anchor-link" href="#usage">Usage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Check current AList version&lt;/p>
&lt;ul>
&lt;li>Management page - Settings - Site - Version&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="infuse">
&lt;a class="heading-anchor-link" href="#infuse">Infuse&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="infuse"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After deploying alist, besides web access, you can access it through apps like Infuse.&lt;/p>
&lt;p>I use Infuse across multiple devices. The common approach is to add alist&amp;rsquo;s exposed WebDAV service to Infuse on Apple TV, which is very convenient for viewing.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Let&amp;rsquo;s start playing with it.&lt;/p></description></item><item><title>Oracle Free Machine Usage</title><link>https://en.1991421.cn/2023/02/04/oracle/</link><pubDate>Sat, 04 Feb 2023 00:12:38 +0800</pubDate><guid>https://en.1991421.cn/2023/02/04/oracle/</guid><description>&lt;blockquote>
&lt;p>Oracle offers permanently free cloud machines, and I recently deployed and started using them. Here&amp;rsquo;s a summary of the experience.&lt;/p>
&lt;/blockquote>
&lt;h2 id="free-machine-application">
&lt;a class="heading-anchor-link" href="#free-machine-application">Free Machine Application&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="free-machine-application"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For application guidance, I recommend checking out &lt;a href="https://xunihao.net/867.html#Oracle-CloudAWS" target="_blank" rel="noopener">this guide&lt;/a>&lt;/p>
&lt;p>If it doesn&amp;rsquo;t work, try changing your proxy IP and attempt multiple times.&lt;/p>
&lt;h3 id="how-many-machines-allowed">
&lt;a class="heading-anchor-link" href="#how-many-machines-allowed">How Many Machines Allowed?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-many-machines-allowed"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>According to some introductions, the maximum is 4 machines with &lt;code>total disk space limited to 200GB&lt;/code>. I tried and only claimed &lt;code>2 machines&lt;/code>, using the default elastic disk space.&lt;/p>
&lt;h3 id="configurationstability">
&lt;a class="heading-anchor-link" href="#configurationstability">Configuration/Stability&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="configurationstability"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>I&amp;rsquo;ve been using it as a proxy for 1.5 years - latency is noticeable but acceptable, after all, it&amp;rsquo;s free so can&amp;rsquo;t complain too much&lt;/li>
&lt;li>Default configuration is 1GB RAM, which is sufficient for running basic services&lt;/li>
&lt;li>10TB/month traffic, shared across multiple instances&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-02-04-121807.jpeg"
alt="https://static.1991421.cn/2023/2023-02-04-121807.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="about-creating-instances">
&lt;a class="heading-anchor-link" href="#about-creating-instances">About Creating Instances&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="about-creating-instances"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Use the default instance image - many others may incur charges, while the default is permanently free&lt;/li>
&lt;li>Default login method is key-based authentication, so be sure to save your private key to avoid being unable to log in after creation&lt;/li>
&lt;/ol>
&lt;h2 id="terminal-login">
&lt;a class="heading-anchor-link" href="#terminal-login">Terminal Login&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="terminal-login"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Default login account is &lt;code>opc&lt;/code>, requiring private key authentication&lt;/p>
&lt;/li>
&lt;li>
&lt;p>After logging in, you can switch to root account using &lt;code>sudo su root&lt;/code> and enable password login&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">vi /etc/ssh/sshd_config
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PermitRootLogin yes
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PasswordAuthentication yes
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">service sshd restart
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Change root user password&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo passwd root
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Default firewall is enabled. If deploying external services, remember to open firewall ports or directly disable the firewall service&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="common-issues">
&lt;a class="heading-anchor-link" href="#common-issues">Common Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="please-login-as-the-user-opc-rather-than-the-user-root">
&lt;a class="heading-anchor-link" href="#please-login-as-the-user-opc-rather-than-the-user-root">Please login as the user &amp;ldquo;opc&amp;rdquo; rather than the user &amp;ldquo;root&amp;rdquo;&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="please-login-as-the-user-opc-rather-than-the-user-root"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>vi ~/.ssh/authorized_keys&lt;/p>
&lt;p>Delete the following section&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command=&amp;#34;echo &amp;#39;Please login as the user \&amp;#34;opc\&amp;#34; rather than the user \&amp;#34;root\&amp;#34;.&amp;#39;;echo;sleep 10;exit 142&amp;#34;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="installing-docker">
&lt;a class="heading-anchor-link" href="#installing-docker">Installing Docker&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installing-docker"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Install Docker CE&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">dnf config-manager --add-repo&lt;span class="o">=&lt;/span>https://download.docker.com/linux/centos/docker-ce.repo
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">dnf install docker-ce -y
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">systemctl start docker
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">systemctl &lt;span class="nb">enable&lt;/span> docker
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">systemctl status docker
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Install Docker Compose&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">dnf install -y curl
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">curl -L https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">chmod +x /usr/local/bin/docker-compose
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">docker-compose --version
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="installing-git">
&lt;a class="heading-anchor-link" href="#installing-git">Installing Git&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installing-git"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">yum install git
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="services-i-personally-deployed">
&lt;a class="heading-anchor-link" href="#services-i-personally-deployed">Services I Personally Deployed&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="services-i-personally-deployed"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I launched 2 instances here - one can serve as a US proxy, while the other can be used to deploy alist/telegram bot services&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Oracle Cloud console is really difficult to use - Tencent Cloud is much better by comparison, but hey, it&amp;rsquo;s permanently free&lt;/li>
&lt;li>For example, the Oracle machine I launched here also works decently as a proxy for accessing openapi and other services&lt;/li>
&lt;/ul>
&lt;h2 id="related-documentation">
&lt;a class="heading-anchor-link" href="#related-documentation">Related Documentation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documentation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.atlantic.net/tutorials/how-to-install-docker-and-docker-compose-on-oracle-linux-8/" target="_blank" rel="noopener">How to Install Docker and Docker Compose on Oracle Linux 8&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Bought EZVIZ C6C Home Camera</title><link>https://en.1991421.cn/2023/01/21/ezviz-camera/</link><pubDate>Sat, 21 Jan 2023 23:18:58 +0800</pubDate><guid>https://en.1991421.cn/2023/01/21/ezviz-camera/</guid><description>&lt;blockquote>
&lt;p>I have two parrots at home and wanted to check on them remotely—especially while traveling—so I bought a home camera. Here are my purchase and usage notes to help others avoid pitfalls.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-01-22-210210.jpeg"
alt="https://static.1991421.cn/2023/2023-01-22-210210.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="brand-choice">
&lt;a class="heading-anchor-link" href="#brand-choice">Brand Choice&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="brand-choice"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I went with EZVIZ. I&amp;rsquo;d tried Lenovo and Xiaomi before—my quick take:&lt;/p>
&lt;ul>
&lt;li>Lenovo&amp;rsquo;s activation flow is terrible and the hardware quality isn&amp;rsquo;t great.&lt;/li>
&lt;li>Xiaomi&amp;rsquo;s app experience is decent but overloaded with ads. One brand-new device prompted me for a firmware upgrade out of the box, and tapping upgrade bricked it. Search online and you&amp;rsquo;ll see tons of similar complaints. The fix requires formatting a memory card and flashing manually. Other annoyances include no 5 GHz Wi-Fi support.&lt;/li>
&lt;/ul>
&lt;p>So those two brands are on my blacklist. After watching a few YouTube reviews, I chose EZVIZ.&lt;/p>
&lt;blockquote>
&lt;p>EZVIZ is a wholly owned subsidiary of Hikvision, a professional security company—so the product matches the parent company&amp;rsquo;s expertise.&lt;/p>
&lt;/blockquote>
&lt;h2 id="picking-a-model">
&lt;a class="heading-anchor-link" href="#picking-a-model">Picking a Model&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="picking-a-model"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>With the brand decided and a 200–300 CNY budget, I landed on the &lt;code>C6C&lt;/code>. I paid &lt;code>233 CNY&lt;/code>, which included a 32 GB Class 10 SD card, via JD (&lt;a href="https://item.jd.com/100029466747.html" target="_blank" rel="noopener">link&lt;/a>) for reference.&lt;/p>
&lt;p>This model ticks the boxes I care about:&lt;/p>
&lt;ol>
&lt;li>&lt;code>4 MP&lt;/code> resolution, which is plenty clear for my needs.&lt;/li>
&lt;li>Supports &lt;code>5 GHz Wi-Fi&lt;/code>, which is rare in this price range and better than certain competitors.&lt;/li>
&lt;/ol>
&lt;h2 id="setup">
&lt;a class="heading-anchor-link" href="#setup">Setup&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="setup"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Activating the EZVIZ was smooth:&lt;/p>
&lt;ul>
&lt;li>Plug in the camera.&lt;/li>
&lt;li>Download and log into the mobile app.&lt;/li>
&lt;li>Follow the prompts in the app to bind and activate the device.&lt;/li>
&lt;/ul>
&lt;h3 id="tips">
&lt;a class="heading-anchor-link" href="#tips">Tips&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tips"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>After a week of use, here are a few handy tricks:&lt;/p>
&lt;ol>
&lt;li>You can &lt;code>disable ads&lt;/code> in the mobile app. Once they&amp;rsquo;re off, even the launch screen is clean.
&lt;ul>
&lt;li>Steps to disable ads are documented &lt;a href="https://github.com/alanhe421/others-note/issues/547" target="_blank" rel="noopener">here&lt;/a>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>EZVIZ offers lots of services—cloud storage, phone alerts, etc.—but almost all of them are paid add-ons, with short trials after activation.
&lt;ul>
&lt;li>Be careful not to subscribe accidentally. Only pay for what you really need.&lt;/li>
&lt;li>For storage, EZVIZ supports SD cards and the cloud. I disabled cloud storage and left out the SD card for now to keep things private; I don&amp;rsquo;t need recordings yet.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>You can share the camera with up to &lt;code>five people&lt;/code> for free. Handy when multiple family members want access.&lt;/li>
&lt;/ol>
&lt;h2 id="impressions">
&lt;a class="heading-anchor-link" href="#impressions">Impressions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="impressions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here are the pros and cons of the C6C:&lt;/p>
&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>The image is sharp—much better than Xiaomi&amp;rsquo;s so-called 2K models.&lt;/li>
&lt;li>5 GHz Wi-Fi support is great; you don&amp;rsquo;t have to switch your phone off your usual network during setup.&lt;/li>
&lt;li>I like the design more than Xiaomi&amp;rsquo;s—it looks nicer overall.&lt;/li>
&lt;/ul>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The EZVIZ app is less polished than Xiaomi&amp;rsquo;s. For example, you have to use on-screen arrow keys to move the camera; gesture control isn&amp;rsquo;t supported.&lt;/li>
&lt;li>Most features beyond live viewing require separate subscriptions, which feels a bit stingy.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Sure, there are downsides, but the core functions—live view, two-way audio, device sharing—work well. At this price, I&amp;rsquo;d still recommend it if you have similar needs.&lt;/p></description></item><item><title>2022 Year-End Review</title><link>https://en.1991421.cn/2023/01/02/2022/</link><pubDate>Mon, 02 Jan 2023 21:32:53 +0800</pubDate><guid>https://en.1991421.cn/2023/01/02/2022/</guid><description>&lt;blockquote>
&lt;p>2023 is here. Looking back at 2022, it&amp;rsquo;s time for my annual summary.&lt;/p>
&lt;/blockquote>
&lt;h2 id="work">
&lt;a class="heading-anchor-link" href="#work">Work&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="work"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>&lt;strong>First Half&lt;/strong>: I primarily focused on business-oriented projects. While the technical skill gain wasn&amp;rsquo;t massive, there were some notable achievements:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Wallet Extension Development&lt;/strong>: This gave me deep insights into dApps, the gRPC communication protocol, and Node.js support for ES modules.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Second Half&lt;/strong>: The focus shifted to &lt;strong>WebShell&lt;/strong> development. This project was technically intensive, and I learned a great deal about terminal emulation and secure communication.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="growth--contributions">
&lt;a class="heading-anchor-link" href="#growth--contributions">Growth &amp;amp; Contributions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="growth--contributions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="open-source">
&lt;a class="heading-anchor-link" href="#open-source">Open Source&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="open-source"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>2022 was even more productive than 2021. Here are the highlights:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://github.com/alanhe421/alfred-workflows" target="_blank" rel="noopener">&lt;strong>Alfred Workflows&lt;/strong>&lt;/a>: Developed &lt;strong>30+&lt;/strong> new workflows, reaching &lt;strong>446 stars&lt;/strong>. This represents a growth of 300 stars over last year. The project has entered a virtuous cycle:&lt;/p>
&lt;ul>
&lt;li>As a power user myself (regularly using tools for OCR, Gongfeng, Whistle, and Surge), I naturally discover bugs and feature needs that drive iterative development.&lt;/li>
&lt;li>The project solves real pain points. I’ve seen active Issues, PRs, and even Sponsors. Some users liked the tools so much they voluntarily submitted them to the official Alfred Gallery for review.
&lt;a href="https://star-history.com/#alanhg/alfred-workflows&amp;amp;Date" target="_blank" rel="noopener">&lt;figure class="image-figure">
&lt;img
src="https://api.star-history.com/svg?repos=alanhg/alfred-workflows&amp;amp;type=Date"
alt="Star History Chart"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/a>&lt;/li>
&lt;li>The repository&amp;rsquo;s infrastructure is maturing, including weekly CI-generated star statistics, automated versioning, README auto-generation from metadata, and standardized GIF recordings.&lt;/li>
&lt;li>Maintaining this repo has also earned me free licenses for &lt;strong>1Password&lt;/strong> and &lt;strong>JetBrains IDEs&lt;/strong>, saving me over 1,000 CNY annually.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://github.com/alanhe421/dash-docset-tcapi" target="_blank" rel="noopener">&lt;strong>dash-docset-tcapi&lt;/strong>&lt;/a>:&lt;/p>
&lt;ul>
&lt;li>Since I frequently use Tencent Cloud APIs, I created a custom Dash docset. This has made API lookup significantly faster.&lt;/li>
&lt;li>Integrated with CI to ensure the docset automatically updates whenever the official documentation changes.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://github.com/alanhe421/toolbox-browser-extensionx" target="_blank" rel="noopener">&lt;strong>toolbox-browser-extensionx&lt;/strong>&lt;/a>:&lt;/p>
&lt;ul>
&lt;li>JetBrains&amp;rsquo; official browser extension doesn&amp;rsquo;t support Tencent Gongfeng. Since I use both WebStorm and VS Code, I modified the official extension to add Gongfeng support and other personalized tweaks to speed up repo cloning.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://github.com/alanhe421/iterm2-trigger" target="_blank" rel="noopener">&lt;strong>iterm2-trigger&lt;/strong>&lt;/a>:&lt;/p>
&lt;ul>
&lt;li>iTerm2 supports triggers to open files. I built this tool to dynamically choose the right editor: Go projects open in GoLand, JS projects in WebStorm, and individual files in VS Code.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://github.com/alanhe421/v2ray-docker" target="_blank" rel="noopener">&lt;strong>v2ray-docker&lt;/strong>&lt;/a>:&lt;/p>
&lt;ul>
&lt;li>Managing proxies across different machines used to be a chore. I encapsulated my preferred setup (WebSocket + HTTPS) into a Docker-based tool. Now, I just submit a simple form to generate a config package and run it.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://github.com/alanhe421/github-issue-bot" target="_blank" rel="noopener">&lt;strong>github-issue-bot&lt;/strong>&lt;/a>:&lt;/p>
&lt;ul>
&lt;li>I use GitHub Issues as a personal knowledge base. To make cross-repo searching easier, I built a Telegram Bot. Now, I can search all my summarized solutions using simple keywords.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-01-11-234317.jpeg"
alt="Issue Bot in Action"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="blogging">
&lt;a class="heading-anchor-link" href="#blogging">Blogging&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="blogging"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>I published &lt;strong>88&lt;/strong> articles this year, bringing the total to &lt;strong>528&lt;/strong>. Most are reflections on technical problems I&amp;rsquo;ve solved. Writing remains my way of &amp;ldquo;leaving footprints in the snow.&amp;rdquo;&lt;/li>
&lt;li>Monetizing the blog remains difficult. Total referral income was under $20, and AdSense only brought in a few dollars. I might need to explore video content on YouTube to supplement this.&lt;/li>
&lt;/ul>
&lt;h3 id="wechat-official-account">
&lt;a class="heading-anchor-link" href="#wechat-official-account">WeChat Official Account&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wechat-official-account"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I maintain a low-frequency account called &amp;quot;Alfred Road to Refinement.&amp;quot; It has &lt;strong>121&lt;/strong> followers. Paid knowledge sharing is tough when so much quality content is available for free.&lt;/p>
&lt;h3 id="learning">
&lt;a class="heading-anchor-link" href="#learning">Learning&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="learning"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I read very few books this year across design, programming, or history. This is something I definitely need to improve in 2023.&lt;/p>
&lt;h3 id="tools">
&lt;a class="heading-anchor-link" href="#tools">Tools&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tools"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>My hardware and software setup is nearing saturation. For a detailed breakdown of the few pieces of gear I did acquire, see &lt;a href="https://en.1991421.cn/2022/07/30/873cbe35/" target="_blank" rel="noopener">Gear Review 2022&lt;/a>.&lt;/p>
&lt;h2 id="travel">
&lt;a class="heading-anchor-link" href="#travel">Travel&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="travel"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Despite the ongoing pandemic, I managed to get out a bit:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>August&lt;/strong>: Handan, Hebei.&lt;/li>
&lt;li>&lt;strong>October&lt;/strong>: Xianning, Hubei.&lt;/li>
&lt;/ul>
&lt;h2 id="review-of-2022-goals">
&lt;a class="heading-anchor-link" href="#review-of-2022-goals">Review of 2022 Goals&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="review-of-2022-goals"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Marriage/Buying a Home&lt;/strong>: Only partially completed. This is now a 2023 priority.&lt;/li>
&lt;li>&lt;strong>Career Advancement&lt;/strong>: Due to the pandemic and company-wide furloughs, this was a difficult year. I did my best given the circumstances.&lt;/li>
&lt;li>&lt;strong>Open Source Growth&lt;/strong>: Exceeded expectations in both quality and quantity of output.&lt;/li>
&lt;li>&lt;strong>Monetization (Mini Programs/Official Account)&lt;/strong>: Still a work in progress.&lt;/li>
&lt;li>&lt;strong>Medium Monetization&lt;/strong>: Abandoned due to the difficulty of linking a bank account without overseas citizenship or identity info.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>The second half of the year involved a lot of overtime. Reflecting on this, I realized some of it was due to inefficient methods leading to a vicious cycle. I need to adjust my workflow in 2023 and communicate more proactively with management.&lt;/li>
&lt;li>With the current economic climate and benefit reductions, I need to think critically about my long-term career path. Value is only created when there is growth and the benefits outweigh the costs.&lt;/li>
&lt;li>I&amp;rsquo;m another year older and looking to start a family. My plan is to get married this year.&lt;/li>
&lt;li>My fitness routine stalled over the past two years. With restrictions lifting, it&amp;rsquo;s time to get back to the gym. Health is the foundation of everything.&lt;/li>
&lt;/ul></description></item><item><title>Apple Family Sharing</title><link>https://en.1991421.cn/2022/11/05/apple/</link><pubDate>Sat, 05 Nov 2022 10:35:27 +0800</pubDate><guid>https://en.1991421.cn/2022/11/05/apple/</guid><description>&lt;blockquote>
&lt;p>Recently, my family also switched to iPhones and entered the Apple ecosystem. I researched family sharing to allow my family to use the Apple ecosystem services I&amp;rsquo;ve been using for years for free and conveniently.&lt;/p>
&lt;p>The official documentation about family sharing is vague, leading to some pitfalls. Here is a summary. Overall, family sharing is quite appealing. I recommend it to those who have purchased many Apple ecosystem services. With family sharing, others can use some excellent services without additional costs. OK, let&amp;rsquo;s start.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-11-05-220803.jpeg"
alt="https://static.1991421.cn/2022/2022-11-05-220803.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="family-sharing">
&lt;a class="heading-anchor-link" href="#family-sharing">Family Sharing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="family-sharing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>This feature can be understood as similar to the YouTube family membership/Spotify family membership. Family-sharing services cover a variety of subscriptions:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>iCloud, Apple Music, Apple TV, and other subscription services&lt;/p>
&lt;ul>
&lt;li>Generally, Apple family membership uses this method. For example, with iCloud space, the initiator cannot directly configure to limit the available size for each person. The entire space size is shared.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>App Store purchased apps [excluding in-app purchases]&lt;/p>
&lt;ul>
&lt;li>&lt;code>In-app purchases are not supported.&lt;/code> For example, the MarginNote app itself is free to download, but Pro features are in-app purchases. Family sharing will not share Pro services; family members must purchase them separately. However, apps like Things, which require a one-time purchase, can be shared.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Please refer to the official website for more details about location information.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Family sharing is account-based, and both iPhone and Mac will be included.&lt;/p>
&lt;!-- more -->
&lt;/li>
&lt;/ol>
&lt;h3 id="about-family-invitations">
&lt;a class="heading-anchor-link" href="#about-family-invitations">About Family Invitations&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="about-family-invitations"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>Personal tests in the China region support &lt;code>repeatedly inviting someone,&lt;/code> which means you can invite someone again even after removing them. There is no limit on the number of times.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The number of people is limited to &lt;code>6,&lt;/code> including the initiator.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="downloading-paid-apps-for-family-members">
&lt;a class="heading-anchor-link" href="#downloading-paid-apps-for-family-members">Downloading Paid Apps for Family Members&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="downloading-paid-apps-for-family-members"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The normal way to search in the store will still show the price. You need to go to Store - Top Right Corner Avatar - Purchased - Select the items purchased by the initiator. Only through this page can you download paid apps for free.&lt;/p>
&lt;h3 id="to-download-shared-content-your-family-must-use-a-valid-payment-method">
&lt;a class="heading-anchor-link" href="#to-download-shared-content-your-family-must-use-a-valid-payment-method">To download shared content, your family must use a valid payment method.&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="to-download-shared-content-your-family-must-use-a-valid-payment-method"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>If this error appears when downloading paid apps on a family member&amp;rsquo;s phone, note that both the initiator and the family member need to have a payment method configured. My test found that this error would still occur if the initiator configured a payment method but the family member did not.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>If the phone shows the payment method edit button as gray, try using a Mac device or a web method.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="at-the-end">
&lt;a class="heading-anchor-link" href="#at-the-end">At the end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="at-the-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Currently, these are the issues I&amp;rsquo;ve found. I will continue to use/observe.&lt;/p></description></item><item><title>Understanding 127.0.0.1 vs. 0.0.0.0</title><link>https://en.1991421.cn/2022/10/17/127-0-0-1/</link><pubDate>Mon, 17 Oct 2022 23:37:04 +0800</pubDate><guid>https://en.1991421.cn/2022/10/17/127-0-0-1/</guid><description>&lt;blockquote>
&lt;p>When starting a web service we often bind to &lt;code>0.0.0.0&lt;/code> or &lt;code>127.0.0.1&lt;/code>. Both work, but they have different behaviors. Here’s a quick refresher.&lt;/p>
&lt;/blockquote>
&lt;p>Example using Express:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">listen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">conf&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">server&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">port&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;0.0.0.0&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sb">`Example app listening on port http://0.0.0.0:&lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">conf&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">server&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">port&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">!`&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="127001">
&lt;a class="heading-anchor-link" href="#127001">127.0.0.1&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="127001"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Loopback address. If the service binds here, neither the public IP nor the LAN IP can reach it.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Even if you disconnect from the network, &lt;code>ping 127.0.0.1&lt;/code> still responds because the packets never leave the host.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-10-23-123702.jpeg"
alt="https://static.1991421.cn/2022/2022-10-23-123702.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>We often use &lt;code>localhost&lt;/code> when binding here. Strictly speaking they’re not the same—&lt;code>localhost&lt;/code> is a hostname that typically maps to &lt;code>127.0.0.1&lt;/code> via &lt;code>/etc/hosts&lt;/code>.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="0000">
&lt;a class="heading-anchor-link" href="#0000">0.0.0.0&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="0000"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Represents all addresses on the machine (loopback, LAN, WAN). Bind here when you want the service reachable via any of them.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Choose deliberately based on exposure. Internal services should bind to &lt;code>127.0.0.1&lt;/code> to reduce risk.&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://zh.wikipedia.org/wiki/Localhost" target="_blank" rel="noopener">https://zh.wikipedia.org/wiki/Localhost&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/watch?v=ahYgoV8MDtg&amp;amp;ab_channel=SoftwareEngenius" target="_blank" rel="noopener">https://www.youtube.com/watch?v=ahYgoV8MDtg&amp;ab_channel=SoftwareEngenius&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://phoenixnap.com/kb/localhost-vs-127-0-0-1" target="_blank" rel="noopener">https://phoenixnap.com/kb/localhost-vs-127-0-0-1&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Buying YouTube Membership (Turkey Region)</title><link>https://en.1991421.cn/2022/10/11/youtube/</link><pubDate>Tue, 11 Oct 2022 00:47:28 +0800</pubDate><guid>https://en.1991421.cn/2022/10/11/youtube/</guid><description>&lt;h2 id="update">
&lt;a class="heading-anchor-link" href="#update">Update&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="update"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>YouTube India/Turkey are now geo‑locked and require locally issued bank cards. If you have a card, continue with the tutorial; otherwise consider a family plan with others.&lt;/p>
&lt;blockquote>
&lt;p>Watching YouTube is a high‑frequency activity for me, but the free tier has too many ads. Surge/AdBlock helps but has side effects, so I opted for a paid membership.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Membership pricing varies by region. India is quite affordable: personal plan (&lt;code>₹129 ≈ ¥11.23 RMB&lt;/code>)/month. Purchasing via India has hurdles - here is my process.&lt;/p>
&lt;/blockquote>
&lt;h2 id="prerequisites">
&lt;a class="heading-anchor-link" href="#prerequisites">Prerequisites&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="prerequisites"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;code>VISA dual‑currency card&lt;/code> for payment&lt;/li>
&lt;li>Indian proxy with a native IP&lt;/li>
&lt;li>Google account&lt;/li>
&lt;/ul>
&lt;h2 id="indian-proxy">
&lt;a class="heading-anchor-link" href="#indian-proxy">Indian proxy&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="indian-proxy"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you already have an Indian proxy, skip this. Otherwise, rent an Indian cloud VM.&lt;/p>
&lt;h3 id="rent-an-indian-vm">
&lt;a class="heading-anchor-link" href="#rent-an-indian-vm">Rent an Indian VM&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="rent-an-indian-vm"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Recommended providers with per‑minute billing:&lt;/p>
&lt;ol>
&lt;li>&lt;a href="https://www.vultr.com/?ref=8363373" target="_blank" rel="noopener">Vultr&lt;/a>&lt;/li>
&lt;li>DigitalOcean&lt;/li>
&lt;/ol>
&lt;h3 id="not-recommended">
&lt;a class="heading-anchor-link" href="#not-recommended">Not recommended&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="not-recommended"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>lightnode - IP may still be recognized as HK&lt;/li>
&lt;/ul>
&lt;h3 id="set-up-the-proxy">
&lt;a class="heading-anchor-link" href="#set-up-the-proxy">Set up the proxy&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="set-up-the-proxy"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>If you use Surge, prefer SSH proxy; if it doesn’t work, configure a proxy chain.&lt;/li>
&lt;li>If SSH proxy isn’t supported, set up a proxy manually: &lt;a href="https://alanhe421.github.io/v2ray-docker" target="_blank" rel="noopener">https://alanhe421.github.io/v2ray-docker&lt;/a>&lt;/li>
&lt;/ol>
&lt;p>After setup, confirm your public IP geolocates to India.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-07-07-014947.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Visiting YouTube should show “India”, and membership pricing should be in INR.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-07-07-015026.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="payment">
&lt;a class="heading-anchor-link" href="#payment">Payment&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="payment"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Once you’re on an Indian IP, you can subscribe and pay. Updating payment methods later isn’t strictly tied to Indian IP (e.g., HK IPs worked); the Indian IP is mainly needed for activation.&lt;/p>
&lt;h2 id="change-google-account-countryaddress">
&lt;a class="heading-anchor-link" href="#change-google-account-countryaddress">Change Google account country/address&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="change-google-account-countryaddress"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;a href="https://pay.google.com/gp/w/u/1/home/addressbook" target="_blank" rel="noopener">https://pay.google.com/gp/w/u/1/home/addressbook&lt;/a>&lt;/p>
&lt;h2 id="join-a-youtube-family-plan">
&lt;a class="heading-anchor-link" href="#join-a-youtube-family-plan">Join a YouTube family plan&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="join-a-youtube-family-plan"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you’re joining a family plan, note: for Indian memberships you need to click the activation link under an Indian IP, otherwise activation fails.&lt;/p>
&lt;h2 id="premium-benefits">
&lt;a class="heading-anchor-link" href="#premium-benefits">Premium benefits&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="premium-benefits"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>My must‑have reasons for Premium:&lt;/p>
&lt;ol>
&lt;li>No ads&lt;/li>
&lt;li>Background playback&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>YouTube Premium is worth the hassle.&lt;/p></description></item><item><title>AddThis Share Button Service</title><link>https://en.1991421.cn/2022/10/07/addthis/</link><pubDate>Fri, 07 Oct 2022 12:01:17 +0800</pubDate><guid>https://en.1991421.cn/2022/10/07/addthis/</guid><description>&lt;blockquote>
&lt;p>Today I integrated my blog with the AddThis service. Here&amp;rsquo;s the process I followed.&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>
&lt;p>Register and log in to &lt;a href="https://www.addthis.com/" target="_blank" rel="noopener">AddThis&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Click on profile - there&amp;rsquo;s a default profile available&lt;/p>
&lt;p>A Profile is essentially a sharing statistics service. Since I want separate statistics for my blog, I&amp;rsquo;ll manage it with a dedicated profile &lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-10-07-120913.jpeg"
alt="https://static.1991421.cn/2022/2022-10-07-120913.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Click on Profile Setting in the top right corner to get the unique ID. Configure this ID in the required location for your site framework. If you&amp;rsquo;re integrating manually, click &amp;ldquo;Get The Code&amp;rdquo; and paste the code into your site &lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-10-07-120939.jpeg"
alt="https://static.1991421.cn/2022/2022-10-07-120939.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>After integration, you need to manually create sharing tools - multiple tools are supported. Without creating tools, the share buttons won&amp;rsquo;t appear when visiting the website.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>After creation, refresh the page to see the share buttons&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>If the buttons still don&amp;rsquo;t appear after following these steps, check the network requests - ad-blocking plugins might be blocking them&lt;/li>
&lt;li>Currently, AddThis is not blocked by the Great Firewall&lt;/li>
&lt;/ol></description></item><item><title>How to Use Certbot (Step-by-Step Guide)</title><link>https://en.1991421.cn/2022/10/06/certbot/</link><pubDate>Thu, 06 Oct 2022 15:25:13 +0800</pubDate><guid>https://en.1991421.cn/2022/10/06/certbot/</guid><description>&lt;blockquote>
&lt;p>Free Let&amp;rsquo;s Encrypt certificates only have a 3-month validity period. To solve automated renewal, I had previously integrated Certbot, but it never worked.&lt;/p>
&lt;p>Recently, checking the logs, I found that the error was due to one of the domains I configured at that time being *.1991421.cn, a wildcard domain. This type of domain requires manually adding DNS TXT records, so my multiple certificate applications have been blocked and not working. To solve this problem, I recently found a solution, which I&amp;rsquo;ll mark here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="automated-renewal">
&lt;a class="heading-anchor-link" href="#automated-renewal">Automated Renewal&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="automated-renewal"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Looking for solutions, I found this library: certbot-letencrypt-wildcardcertificates-alydns-au.&lt;/p>
&lt;p>The basic implementation principle is to use APIs provided by DNS service providers to solve the problem of automatically updating DNS records, while Certbot exposes hooks so it can be integrated with the domain application process. This library also supports Tencent Cloud/Alibaba Cloud services.&lt;/p>
&lt;p>Overall it&amp;rsquo;s OK, but there are a few issues:&lt;/p>
&lt;ol>
&lt;li>Not all domains are supported, such as VIP domains, which need to be added manually.&lt;/li>
&lt;li>The certbot-auto script doesn&amp;rsquo;t exist, but research shows you can directly switch to certbot instead.&lt;/li>
&lt;/ol>
&lt;p>After figuring this out, I modified it. If you need it, you can directly use this library: &lt;a href="https://github.com/alanhe421/certbot-letencrypt-wildcardcertificates-alydns-au" target="_blank" rel="noopener">https://github.com/alanhe421/certbot-letencrypt-wildcardcertificates-alydns-au&lt;/a>&lt;/p>
&lt;p>Testing shows this is very convenient. After the first manual application, it can be automated afterwards. Whether it actually works can be checked when it&amp;rsquo;s about to expire to see if it renews normally.&lt;/p>
&lt;p>This way, under normal circumstances, you don&amp;rsquo;t need to worry about domain renewal issues.&lt;/p>
&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>For example, CentOS comes with a Python environment by default, so it&amp;rsquo;s recommended to choose Python.&lt;/li>
&lt;li>There&amp;rsquo;s no need to install certbot using Docker; installing it globally is fine and very convenient.&lt;/li>
&lt;/ol></description></item><item><title>JSON vs BSON Comparison</title><link>https://en.1991421.cn/2022/09/24/json-vs-bson/</link><pubDate>Sat, 24 Sep 2022 19:58:15 +0800</pubDate><guid>https://en.1991421.cn/2022/09/24/json-vs-bson/</guid><description>&lt;blockquote>
&lt;p>Recently while working on service integration, the other service provided data in BSON-serialized binary format. I only knew about JSON before, not BSON. Here&amp;rsquo;s a summary.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-09-25-123303.jpeg"
alt="https://static.1991421.cn/2022/2022-09-25-123303.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="bson">
&lt;a class="heading-anchor-link" href="#bson">BSON&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bson"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>BSON is the binary version of JSON data - JSON serializes objects into strings, while BSON serializes into binary&lt;/li>
&lt;li>BSON supports richer data formats, such as Date/Binary types&lt;/li>
&lt;li>The JavaScript library for BSON processing is &lt;a href="https://github.com/mongodb/js-bson" target="_blank" rel="noopener">js-bson&lt;/a>, which supports both browser and Node.js environments&lt;/li>
&lt;/ol>
&lt;h3 id="example">
&lt;a class="heading-anchor-link" href="#example">Example&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="example"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Serialized as string
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">JSON&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">stringify&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="nx">a&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">104&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">101&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">108&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">108&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">111&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">32&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">119&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">111&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">114&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">108&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">100&lt;/span>&lt;span class="p">]})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Serialized as buffer - binary data type
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">BSON&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">serialize&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="nx">a&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">104&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">101&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">108&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">108&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">111&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">32&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">119&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">111&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">114&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">108&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">100&lt;/span>&lt;span class="p">]})&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="bson-vs-json">
&lt;a class="heading-anchor-link" href="#bson-vs-json">BSON vs JSON&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bson-vs-json"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>As shown above with JSON serialization, it carries minimal metadata besides the actual data, resulting in higher space efficiency. However, BSON carries more metadata, so you&amp;rsquo;ll find that the same object takes up more space when serialized with BSON. But this isn&amp;rsquo;t absolute - in specific scenarios, BSON can actually use less space than JSON. For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">let&lt;/span> &lt;span class="nx">now&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nb">Date&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">let&lt;/span> &lt;span class="nx">data1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">JSON&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">stringify&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="nx">a&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">now&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">let&lt;/span> &lt;span class="nx">data2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">BSON&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">serialize&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="nx">a&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">now&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">Buffer&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">from&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">data1&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">byteLength&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">data2&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">byteLength&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>JSON serializes into strings, making it more human-readable. Binary data, without deserialization, cannot be understood directly.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>BSON carries metadata, essentially trading space for time, making traversal, querying, and modification relatively faster.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://stackoverflow.com/questions/12601890/compare-json-and-bson" target="_blank" rel="noopener">https://stackoverflow.com/questions/12601890/compare-json-and-bson&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.geeksforgeeks.org/difference-between-json-and-bson/" target="_blank" rel="noopener">https://www.geeksforgeeks.org/difference-between-json-and-bson/&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Shortcuts on iPhone</title><link>https://en.1991421.cn/2022/08/26/iphoneshortcuts/</link><pubDate>Fri, 26 Aug 2022 23:43:20 +0800</pubDate><guid>https://en.1991421.cn/2022/08/26/iphoneshortcuts/</guid><description>&lt;blockquote>
&lt;p>On Mac, Alfred already boosts efficiency. On iPhone, the official Shortcuts app can also help. Here are some workflows I use.&lt;/p>
&lt;/blockquote>
&lt;img src="https://static.1991421.cn/2022/2022-08-26-235239.jpeg" alt="https://static.1991421.cn/2022/2022-08-26-235239.jpeg" style="zoom:33%;" />
&lt;h2 id="common-shortcuts">
&lt;a class="heading-anchor-link" href="#common-shortcuts">Common shortcuts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-shortcuts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Quickly open ID document&lt;/p>
&lt;ul>
&lt;li>I renew every three days for health checks. To make it easy, I store my ID file in iCloud and use a shortcut to open it. I avoid Photos because it contains personal pictures, and ID info is sensitive. So I store it as a file instead.&lt;!-- more -->&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Unicom SMS quick send&lt;/p>
&lt;ul>
&lt;li>For common SMS like points redemption, I add them as options and trigger send directly.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Quickly open cycling workout (Go)&lt;/p>
&lt;ul>
&lt;li>
&lt;p>For daily commuting, I want to quickly open Workout -&amp;gt; Cycling. I built a shortcut for that.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>I also show it on Apple Watch and place it prominently on the watch face for one‑tap start.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-08-27-000045.jpeg"
alt="https://static.1991421.cn/2022/2022-08-27-000045.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Make GIF&lt;/p>
&lt;p>To enrich WeChat stickers, I often record short videos and convert to GIF with one tap. Then in WeChat, long‑press to add as a sticker.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>WeChat scan&lt;/p>
&lt;p>This simply opens the WeChat scan URL scheme: &lt;code>weixin://scanqrcode&lt;/code>&lt;/p>
&lt;p>I summarized a list of common app URL schemes &lt;a href="https://github.com/alanhe421/url-scheme" target="_blank" rel="noopener">here&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>AirDrop latest image&lt;/p>
&lt;p>Sometimes after saving an image, I want to send it to another device without searching in Photos.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>ChatGPT Chinese‑English translation&lt;/p>
&lt;ul>
&lt;li>Requires the ChatGPT iOS app&lt;/li>
&lt;li>&lt;a href="https://www.icloud.com/shortcuts/863dc4c705b14cf8b7ac2bd7c9b5bab9" target="_blank" rel="noopener">Install&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>etc.&lt;/p>
&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>These workflows are based on my own needs and are not universal. This is more about ideas; build your own based on your use cases. The barrier is low.&lt;/li>
&lt;li>What Shortcuts can do depends on the host system (iPhone/Mac, etc.) and the capabilities exposed by apps. Understand the limitations.&lt;/li>
&lt;/ol></description></item><item><title>A Trip to Handan, Hebei</title><link>https://en.1991421.cn/2022/08/15/handan-trip/</link><pubDate>Mon, 15 Aug 2022 22:39:55 +0800</pubDate><guid>https://en.1991421.cn/2022/08/15/handan-trip/</guid><description>&lt;blockquote>
&lt;p>I went to Handan, Hebei from the 12th to the 15th, walking around and experiencing different aspects of the city. Here&amp;rsquo;s what I recorded.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-08-15-232855.jpeg"
alt="A Trip to Handan, Hebei - Figure 1"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="accommodation">
&lt;a class="heading-anchor-link" href="#accommodation">Accommodation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accommodation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I stayed at Hanting Hotel for all 3 days in the urban area. This time, I tried Hanting Premium. After checking, I found that Premium is a brand upgrade from the original Hanting Economy Hotel, but I really didn&amp;rsquo;t see much improvement—only a slight price increase.&lt;/p>
&lt;p>However, there are a few things I liked about Hanting Hotel:&lt;/p>
&lt;ol>
&lt;li>Convenient &lt;code>self-service breakfast&lt;/code>—not the most delicious, but very convenient.&lt;/li>
&lt;li>&lt;code>Self-service luggage storage&lt;/code>—directly scan your ID card to store luggage, which is very convenient and supports large items.&lt;/li>
&lt;li>Provides &lt;code>iced drinks and tea&lt;/code>; the cookies are great. It&amp;rsquo;s been really hot lately, so being able to have a lemon iced drink right when entering the hotel was wonderful. Unfortunately, not all stores have this. I happened to switch hotels and found that some have fewer offerings.&lt;/li>
&lt;li>The hotel provides a &lt;code>24-hour beverage vending service&lt;/code>, which is a godsend for people like me who love iced drinks with extra ice. A lemon cool drink at night is really great.&lt;/li>
&lt;/ol>
&lt;p>For a few hundred yuan, Hanting is still a good choice. However, the so-called membership discounts don&amp;rsquo;t feel particularly cost-effective. If you&amp;rsquo;re paying for personal consumption, the discounts available on platforms like Gaode Maps are also very good.&lt;/p>
&lt;!-- more -->
&lt;h2 id="food">
&lt;a class="heading-anchor-link" href="#food">Food&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="food"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I visited three night markets in the urban area: &lt;code>Xinhua Night Market&lt;/code>, &lt;code>Chengnan Night Market&lt;/code>, and &lt;code>Tangren Street Night Market&lt;/code>. I also walked around the nearby roads for a long time. Overall, I found many night stalls with delicious and affordable food. I really liked the flowing heart wide noodles, sweet potato fries, and fried skewers—unhealthy, but still delicious&amp;hellip;&lt;/p>
&lt;p>During my time in Handan, I didn&amp;rsquo;t see any Nayuki&amp;rsquo;s Tea or HeyTea stores. Instead, there were more Mixue Ice Cream &amp;amp; Tea and Shanghai Ayi stores, which says something about the local average consumption level.&lt;/p>
&lt;h3 id="transportation">
&lt;a class="heading-anchor-link" href="#transportation">Transportation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="transportation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>
&lt;p>On the one hand, I was not familiar with the area; on the other hand, electric bikes were too reckless, so I only rode once in a few days—safety first. After that, I took taxis the whole time. The cost wasn&amp;rsquo;t too high, acceptable.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>I also visited Daming County under Handan City. The high-speed train from Beijing to Handan took 2 hours, but getting to Daming by bus took 1 hour, which was quite troublesome.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>When returning to Beijing at Handan East Railway Station, I found it was very crowded, and it was still Monday. So I can only draw a rough conclusion: transportation is not very convenient, so all the pressure is concentrated at Handan East Station.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h3 id="attractions">
&lt;a class="heading-anchor-link" href="#attractions">Attractions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="attractions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>I visited &lt;code>Daming Ancient City&lt;/code>/&lt;code>Guangfu Ancient City&lt;/code>. Daming Ancient City is free. These are Ming and Qing Dynasty ancient cities, and I didn&amp;rsquo;t expect them to be so well preserved. Looking at the ancient city walls, I couldn&amp;rsquo;t help but imagine those historical dramas—it was quite nice. History rolls forward; through these precious historical sites, let&amp;rsquo;s imagine the past. Recommended for history enthusiasts. The only bad impression was the overall ticket-buying experience at Guangfu Ancient City, which showed how unregulated and rogue it could be.
&lt;ul>
&lt;li>Buying tickets online through platforms like Ctrip was successful but could not be validated, so we had to buy tickets on-site. This was really rogue.&lt;/li>
&lt;li>Tickets for Guangfu Mansion can be bought online but are only valid 2 hours after purchase.&lt;/li>
&lt;li>When buying tickets for Wujia Courtyard on-site, the staff casually said that once you enter, you can&amp;rsquo;t come out and re-enter. We directly refuted by saying, &amp;ldquo;Look at the back—it says &amp;lsquo;one day&amp;rsquo; and there&amp;rsquo;s no limit on the number of entries.&amp;rdquo; The staff had nothing to say. So can staff just make up random rules without being able to justify them?&lt;/li>
&lt;li>When buying tickets for Wujia Courtyard on-site, the staff asked if we had bought the city wall ticket. If not, we could get a 5 yuan discount here. But when buying the city wall ticket, no one mentioned this. So it seems that offline prices vary in different places—everything is random.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Handan &lt;code>Meile City&lt;/code> is the largest shopping mall in the city. The night view is great, and the snacks in the supermarket are wonderful—I think they taste better than those in restaurants.&lt;/li>
&lt;li>I noticed that many places didn&amp;rsquo;t have as strict health code/mask requirements as Beijing. It gave me the feeling that others were living a normal life while I was the only clown. I hope everything opens up soon.&lt;/li>
&lt;li>&lt;code>Handan Botanical Garden&lt;/code> is quite large, but it&amp;rsquo;s a bit noisy because it&amp;rsquo;s close to the railway station.&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>It&amp;rsquo;s been really hot lately, so I didn&amp;rsquo;t visit many outdoor attractions. But the ancient cities are still worth visiting—after all, these are real historical relics. However, you need to be mentally prepared for the unregulated aspects mentioned above.&lt;/li>
&lt;li>I saw that the night market culture in Handan is great, so there are really many delicious foods. Beijingers can only be envious of this.&lt;/li>
&lt;/ul></description></item><item><title>How to Use Spotify (Step-by-Step Guide)</title><link>https://en.1991421.cn/2022/07/30/spotify/</link><pubDate>Sat, 30 Jul 2022 22:36:27 +0800</pubDate><guid>https://en.1991421.cn/2022/07/30/spotify/</guid><description>&lt;blockquote>
&lt;p>Spotify is a world-famous streaming service I’d never tried. I recently wanted a better music app and decided to give it a shot. Here are my notes.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-07-30-224316.jpeg"
alt="https://static.1991421.cn/2022/2022-07-30-224316.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="before-you-start">
&lt;a class="heading-anchor-link" href="#before-you-start">Before You Start&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="before-you-start"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Using Spotify from China has a few hurdles:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Mainland networks block it—use a proxy (Surge, Shadowrocket, or another VPN).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Free accounts work but have heavy restrictions. I’m happy to pay for reasonable services, so this isn’t a deal-breaker.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-07-30-224200.jpeg"
alt="https://static.1991421.cn/2022/2022-07-30-224200.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>It’s absent from the Chinese App Store; you need a foreign Apple ID.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Accept these constraints and you’re ready to proceed.&lt;/p>
&lt;h2 id="registration">
&lt;a class="heading-anchor-link" href="#registration">Registration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="registration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Using a proxy may trigger: “Your account was not created. Your device appears to be connected to a proxy or VPN service…” Many proxy IPs belong to cloud providers, so Spotify flags them.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-08-07-131456.jpeg"
alt="https://static.1991421.cn/2022/2022-08-07-131456.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>I registered with a VMess service routed through Macau. Check your IP at &lt;a href="https://whoer.net/" target="_blank" rel="noopener">https://whoer.net/&lt;/a> first—make sure the IP and ISP look like a normal residential provider. DNS didn’t matter in my tests.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-07-30-225150.jpeg"
alt="https://static.1991421.cn/2022/2022-07-30-225150.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Sign up using a region-specific URL:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.spotify.com/tw/signup" target="_blank" rel="noopener">https://www.spotify.com/tw/signup&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.spotify.com/hk-zh/signup" target="_blank" rel="noopener">https://www.spotify.com/hk-zh/signup&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.spotify.com/us/signup" target="_blank" rel="noopener">https://www.spotify.com/us/signup&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Once registered, you can use the free tier.&lt;/p>
&lt;h2 id="using-spotify">
&lt;a class="heading-anchor-link" href="#using-spotify">Using Spotify&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="using-spotify"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>You can change your region in your profile, provided you haven’t subscribed yet. I switched to the Philippines. You can only switch to the region matching your current proxy. I recommend &lt;a href="https://www.lightnode.com/?inviteCode=64ED5X&amp;amp;promoteWay=LINK" target="_blank" rel="noopener">&lt;code>LightNode VPS&lt;/code>&lt;/a> for Philippines nodes.&lt;/li>
&lt;li>The iOS app lets you set Spotify’s language independently of iOS.&lt;/li>
&lt;li>New accounts typically receive a short trial of Premium (about two weeks) before reverting to Free with ads.&lt;/li>
&lt;/ol>
&lt;h2 id="premium-options">
&lt;a class="heading-anchor-link" href="#premium-options">Premium Options&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="premium-options"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I suggest the Family plan; the Philippines region is the cheapest. I’m currently on a Philippines family group (≈21 CNY/quarter).&lt;/p>
&lt;p>Key points:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Joining a family plan requires an email registered in the same region. When clicking the invite link, ensure your IP matches (e.g., Philippines). Enter the family address supplied by the host and you’ll see a confirmation like this:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-11-09-204033.jpeg"
alt="https://static.1991421.cn/2022/2022-11-09-204033.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>If you prefer solo premium, pricing varies by region—the Philippines remains the lowest.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Paying yourself is tricky. For example, Hong Kong plans need Hong Kong payment methods; PayPal requires a Hong Kong account; mainland Visa cards fail. I haven’t solved this yet, so I stick with family plans.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The iOS app doesn’t support in-app purchases; subscribe via the web.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-08-07-150914.jpeg"
alt="https://static.1991421.cn/2022/2022-08-07-150914.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>(Price chart from &lt;a href="https://sspai.com/post/55367" target="_blank" rel="noopener">https://sspai.com/post/55367&lt;/a>)&lt;/p>
&lt;h2 id="drawback">
&lt;a class="heading-anchor-link" href="#drawback">Drawback&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="drawback"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>One annoyance: &lt;code>Chinese lyrics are only in Traditional characters&lt;/code>—no Simplified support yet.&lt;/p>
&lt;h2 id="other-services-i-tried">
&lt;a class="heading-anchor-link" href="#other-services-i-tried">Other Services I Tried&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other-services-i-tried"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>NetEase Cloud Music&lt;/strong> – formerly great, now overloaded with social content + copyright gaps.&lt;/li>
&lt;li>&lt;strong>QQ Music&lt;/strong> – social-heavy, shows ads even for premium, pushes MVs/livestreams when I just want songs.&lt;/li>
&lt;li>&lt;strong>Apple Music&lt;/strong> – search is painful; Chinese songs often require English names, lyrics are incomplete.&lt;/li>
&lt;li>&lt;strong>YouTube Music&lt;/strong> – search limitations similar to Apple Music.&lt;/li>
&lt;/ol>
&lt;p>In 2024 it’s surprisingly hard to find a satisfying music app. Spotify feels like the best compromise so far.&lt;/p>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>There’s a reason Spotify is popular. After trying it myself, I’m staying. Give it a shot if you can navigate the regional hurdles.&lt;/p></description></item><item><title>Visiting Peking University People’s Hospital (PKUPH)</title><link>https://en.1991421.cn/2022/07/24/hospital-visit-peking-university/</link><pubDate>Sun, 24 Jul 2022 11:29:30 +0800</pubDate><guid>https://en.1991421.cn/2022/07/24/hospital-visit-peking-university/</guid><description>&lt;blockquote>
&lt;p>Treatment at Hospital 306 didn’t go smoothly, so I switched to PKUPH. The care is stronger overall, but the process still has its pain points. Here are my notes.&lt;/p>
&lt;/blockquote>
&lt;h2 id="what-to-bring">
&lt;a class="heading-anchor-link" href="#what-to-bring">What to Bring&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-to-bring"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Social security card — only required the first time to activate the hospital’s e-insurance; not needed afterward&lt;/li>
&lt;li>Phone — for booking appointments and paying bills&lt;/li>
&lt;/ul>
&lt;h2 id="full-visit-flow">
&lt;a class="heading-anchor-link" href="#full-visit-flow">Full Visit Flow&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="full-visit-flow"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;code>WeChat 114 registration&lt;/code> — note that it’s the service account, not the mini program
&lt;ul>
&lt;li>Each doctor has different clinic hours. I recommend sticking with the same doctor to avoid repeating your case history, even if it’s in the records. The doctor I like is on duty Tuesdays and Wednesdays, so I only book those days.&lt;/li>
&lt;li>New appointments are released at 8:00 a.m.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Scan the QR code at the entrance to fill out the pandemic screening form.&lt;/li>
&lt;li>Use the self-service kiosk on the left side of the entrance to print your visit slip. Paying with the phone—Alipay + e-insurance—works well.&lt;/li>
&lt;li>Head to the outpatient building for your consultation. Dermatology is on the 4th floor; scan the code to check in and wait to be called.&lt;/li>
&lt;li>After the visit, pay for medications at any self-service kiosk on the 4th floor or elsewhere.&lt;/li>
&lt;li>Pick up your meds on the 1st or 4th floor, depending on what was prescribed.&lt;/li>
&lt;li>I need paper invoices for commercial insurance reimbursement, and the hospital doesn’t issue e-invoices, so I have to queue at the staffed payment window to print them. Sometimes you have to remind the doctor to include the registration fee on that invoice.&lt;/li>
&lt;/ol>
&lt;h2 id="friction-points">
&lt;a class="heading-anchor-link" href="#friction-points">Friction Points&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="friction-points"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Some ticketing kiosks at the entrance are out of order with no signage. If something seems off, flag down a staff member instead of wasting time troubleshooting it yourself.&lt;/li>
&lt;li>The medication pickup line for dermatology shares the same queue as in-clinic treatments, so it can crawl. Just ask the outpatient doctor to arrange for someone to fetch the meds. It takes minutes versus an hour of waiting.&lt;/li>
&lt;li>Medical records don’t sync across hospitals. Exams done at Hospital A may not be recognized at Hospital B, which wastes both time and money. Stick with one hospital for the same condition if you can.&lt;/li>
&lt;/ol>
&lt;h2 id="summary">
&lt;a class="heading-anchor-link" href="#summary">Summary&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="summary"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Compared with the dermatology department at Hospital 306, PKUPH feels more professional, so I’ve been doing all related treatments here lately.&lt;/li>
&lt;li>Hospital visits reveal plenty of inefficiencies. Use every trick you can to save your own time.&lt;/li>
&lt;/ol></description></item><item><title>Character Encoding Basics</title><link>https://en.1991421.cn/2022/07/03/encoding-problems/</link><pubDate>Sun, 03 Jul 2022 17:29:23 +0800</pubDate><guid>https://en.1991421.cn/2022/07/03/encoding-problems/</guid><description>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-07-05-225814.jpeg"
alt="https://static.1991421.cn/2022/2022-07-05-225814.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="common-encoding-settings">
&lt;a class="heading-anchor-link" href="#common-encoding-settings">Common encoding settings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-encoding-settings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>IDE/editors&lt;/p>
&lt;p>Screenshot shows configuring the encoding for a single file in WebStorm.
&lt;figure class="image-figure">
&lt;img
src="https://user-images.githubusercontent.com/9245110/176985913-55656f25-b692-4596-a13b-2a0cc3d1c396.png"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Page source&lt;/p>
&lt;p>Screenshot of the page source in Chrome.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://user-images.githubusercontent.com/9245110/176985935-03ad9b0a-3dfa-4ac1-a6cb-8d0f0c98408b.png"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://user-images.githubusercontent.com/9245110/177030627-1e4f1f15-00b4-4db0-b6f6-05a9c78ed7be.png"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Network requests&lt;/p>
&lt;p>Screenshot of the encoding info shown for an XHR request in Chrome DevTools.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://user-images.githubusercontent.com/9245110/176986086-a740b39e-9adb-41b0-b374-21cebe639c46.png"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://user-images.githubusercontent.com/9245110/177032941-1f5e9d8b-6895-4916-ac94-56dadf72fa65.png"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://en.1991421.cn/Users/alanhe/Library/Application%20Support/typora-user-images/image-20220724223834393.png"
alt="image-20220724223834393"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ol start="4">
&lt;li>
&lt;p>URLs&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://user-images.githubusercontent.com/9245110/177030718-4f4f6830-cfa9-4f40-9250-44795b0cd2cd.png"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Programming languages&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://user-images.githubusercontent.com/9245110/176986116-20a972ea-f004-49c4-9e1f-b27231e4f5a3.png"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="why-encodings-exist">
&lt;a class="heading-anchor-link" href="#why-encodings-exist">Why encodings exist&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-encodings-exist"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Inside a computer, everything is ultimately stored as the binary digits 0 and 1. Encodings define how characters are persisted and rendered.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-07-05-225147.jpeg"
alt="https://static.1991421.cn/2022/2022-07-05-225147.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="ascii-vs-unicode-vs-utf-8">
&lt;a class="heading-anchor-link" href="#ascii-vs-unicode-vs-utf-8">ASCII vs. Unicode vs. UTF-8&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ascii-vs-unicode-vs-utf-8"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>A few concepts show up frequently; it helps to separate them clearly.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>ASCII&lt;/strong> is an encoding based on the Latin alphabet that represents 128 characters, so it cannot represent many languages (Chinese included).&lt;/p>
&lt;ul>
&lt;li>Those 128 characters cover &lt;code>a-z&lt;/code>, &lt;code>A-Z&lt;/code>, &lt;code>0-9&lt;/code>, punctuation such as &lt;code>+-&lt;/code>, and some control characters such as &lt;code>ACK&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Unicode&lt;/strong> is a character set whose goal is to assign a code to every symbol in every language. For example, the Chinese character for “middle” is &lt;code>U+4E2D&lt;/code>, while the Japanese katakana character “u” is &lt;code>U+30A6&lt;/code>. Every symbol maps to a unique code point. The code points themselves are fixed-width, so naïvely storing everything in Unicode would waste space. Unicode is also called Universal Coded Character Set or UCS.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>UTF-8/ASCII&lt;/strong> are encodings — they define how code points are stored or transmitted. UTF-8 is one implementation of Unicode. For example, that “middle” character becomes &lt;code>&amp;amp;#x4E2D;&lt;/code> when encoded in UTF-8.&lt;/p>
&lt;ul>
&lt;li>UTF-8 is backward compatible with ASCII.&lt;/li>
&lt;li>If Unicode is the interface, the various UTF encodings are implementations.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="timeline">
&lt;a class="heading-anchor-link" href="#timeline">Timeline&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="timeline"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The first ASCII standard was published in 1963.&lt;/li>
&lt;li>Unicode 1.0 arrived in 1991.&lt;/li>
&lt;li>UTF-8 debuted in 1992.&lt;/li>
&lt;/ol>
&lt;h3 id="where-is-a-files-encoding-stored">
&lt;a class="heading-anchor-link" href="#where-is-a-files-encoding-stored">Where is a file&amp;rsquo;s encoding stored?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="where-is-a-files-encoding-stored"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Per the Unicode spec, a file may start with a special character called the zero-width no-break space to indicate encoding order (the BOM).&lt;/p>
&lt;h2 id="other-encodings">
&lt;a class="heading-anchor-link" href="#other-encodings">Other encodings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other-encodings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="base64">
&lt;a class="heading-anchor-link" href="#base64">Base64&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="base64"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Characteristics:&lt;/p>
&lt;ul>
&lt;li>Any binary file can be converted into printable text so that it can be edited as plain text.&lt;/li>
&lt;li>It provides a lightweight form of obfuscation.&lt;/li>
&lt;/ul>
&lt;p>Aside from Base64, there is &lt;a href="https://github.com/cryptocoinjs/bs58" target="_blank" rel="noopener">Base58&lt;/a>. Compared with Base64, it drops characters that are easy to confuse: the digit &lt;code>0&lt;/code>, uppercase &lt;code>O&lt;/code>, uppercase &lt;code>I&lt;/code>, lowercase &lt;code>l&lt;/code>, and the symbols &lt;code>+&lt;/code> and &lt;code>/&lt;/code>, i.e., 64 − 6.&lt;/p>
&lt;h3 id="url-encoding">
&lt;a class="heading-anchor-link" href="#url-encoding">URL encoding&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="url-encoding"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://user-images.githubusercontent.com/9245110/177030718-4f4f6830-cfa9-4f40-9250-44795b0cd2cd.png"
alt="image"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>JavaScript provides helpers such as &lt;code>encodeURI&lt;/code> and &lt;code>encodeURIComponent&lt;/code> for URL encoding.&lt;/p>
&lt;h2 id="why-mojibake-happens">
&lt;a class="heading-anchor-link" href="#why-mojibake-happens">Why mojibake happens&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-mojibake-happens"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Because the encoding used to store the data doesn&amp;rsquo;t match the encoding used to read/display it.&lt;/p>
&lt;p>![image-20220703175332829](/Users/alanhe/Library/Mobile Documents/com&lt;del>apple&lt;/del>CloudDocs/Typora/image-20220703175332829.png)&lt;/p>
&lt;p>![image-20220703175750816](/Users/alanhe/Library/Mobile Documents/com&lt;del>apple&lt;/del>CloudDocs/Typora/image-20220703175750816.png)&lt;/p>
&lt;p>![image-20220703180749581](/Users/alanhe/Library/Mobile Documents/com&lt;del>apple&lt;/del>CloudDocs/Typora/image-20220703180749581.png)&lt;/p>
&lt;p>A quick example: ISO-8859-1 is based on ASCII and adds 96 characters in the 0xA0–0xFF range for Latin languages with diacritics, but it still cannot represent Chinese characters. UTF-16 is not backward compatible with UTF-8.&lt;/p>
&lt;h2 id="detecting-encodings">
&lt;a class="heading-anchor-link" href="#detecting-encodings">Detecting encodings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="detecting-encodings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;a href="https://github.com/aikuyun/iterm2-zmodem/blob/master/iterm2-recv-zmodem.sh" target="_blank" rel="noopener">https://github.com/aikuyun/iterm2-zmodem/blob/master/iterm2-recv-zmodem.sh&lt;/a>&lt;/p>
&lt;p>![image-20220703211018747](/Users/alanhe/Library/Mobile Documents/com&lt;del>apple&lt;/del>CloudDocs/Typora/image-20220703211018747.png)&lt;/p>
&lt;p>![image-20220703211555644](/Users/alanhe/Library/Mobile Documents/com&lt;del>apple&lt;/del>CloudDocs/Typora/image-20220703211555644.png)&lt;/p>
&lt;p>![image-20220703214219452](/Users/alanhe/Library/Mobile Documents/com&lt;del>apple&lt;/del>CloudDocs/Typora/image-20220703214219452.png)&lt;/p>
&lt;h2 id="related-docs">
&lt;a class="heading-anchor-link" href="#related-docs">Related docs&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-docs"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;a href="https://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html" target="_blank" rel="noopener">Notes on ASCII, Unicode, and UTF-8&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/" target="_blank" rel="noopener">The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tool.oschina.net/commons?type=4" target="_blank" rel="noopener">ASCII chart&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://zh.m.wikipedia.org/zh-hans/%E4%BA%82%E7%A2%BC" target="_blank" rel="noopener">Mojibake&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://cloud.tencent.com/developer/article/1442847" target="_blank" rel="noopener">Why do we need URL encoding?&lt;/a>&lt;/li>
&lt;/ol></description></item><item><title>How to Use Whistle (Step-by-Step Guide)</title><link>https://en.1991421.cn/2022/06/28/whistle/</link><pubDate>Tue, 28 Jun 2022 17:53:01 +0800</pubDate><guid>https://en.1991421.cn/2022/06/28/whistle/</guid><description>&lt;blockquote>
&lt;p>During frontend debugging, our team uses Whistle to proxy specific resources to target addresses.&lt;/p>
&lt;/blockquote>
&lt;h2 id="install-whistle">
&lt;a class="heading-anchor-link" href="#install-whistle">Install Whistle&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="install-whistle"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Install &lt;code>NodeJS&lt;/code>&lt;/p>
&lt;p>Recommended via NVM. Windows: &lt;a href="https://github.com/coreybutler/nvm-windows" target="_blank" rel="noopener">nvm-windows&lt;/a>. Others: &lt;a href="https://github.com/nvm-sh/nvm" target="_blank" rel="noopener">nvm&lt;/a>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Install Whistle&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">npm install -g whistle
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Start Whistle&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Run in terminal&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">w2 start
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Check status&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">w2 status
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Open &lt;a href="http://127.0.0.1:8899" target="_blank" rel="noopener">http://127.0.0.1:8899&lt;/a> in a browser&lt;/p>
&lt;/li>
&lt;li>
&lt;p>HTTPS interception&lt;/p>
&lt;p>To proxy HTTPS URLs, enable HTTPS:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Turn on HTTPS switches&lt;/p>
&lt;img src="https://static.1991421.cn/2022/2022-06-28-175913.jpeg" alt="https://static.1991421.cn/2022/2022-06-28-175913.jpeg" style="zoom:50%;" />
&lt;/li>
&lt;li>
&lt;p>Download the root certificate and install it&lt;/p>
&lt;p>Besides the popup, you can download it via &lt;a href="http://rootca.pro" target="_blank" rel="noopener">http://rootca.pro&lt;/a> if the Whistle proxy is active.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Trust the certificate in &lt;code>Keychain Access&lt;/code>&lt;/p>
&lt;img src="https://static.1991421.cn/2022/2022-09-01-192741.jpeg" alt="https://static.1991421.cn/2022/2022-09-01-192741.jpeg" />
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="browser-extension">
&lt;a class="heading-anchor-link" href="#browser-extension">Browser extension&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="browser-extension"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Install the &lt;a href="https://chrome.google.com/webstore/detail/whistle-%E7%AC%AC%E4%B8%89%E6%96%B9%E6%8F%92%E4%BB%B6/ibhpjiafjijjpofblhamncmhlicfcofm?utm_source=chrome-ntp-icon" target="_blank" rel="noopener">Whistle Chrome extension&lt;/a>&lt;/p>
&lt;ul>
&lt;li>To route browser requests through Whistle, install the extension and enable Whistle proxy&lt;/li>
&lt;li>If the extension is unavailable in your store, use &lt;a href="https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif?utm_source=chrome-ntp-icon" target="_blank" rel="noopener">SwitchyOmega&lt;/a>&lt;/li>
&lt;li>Safari has no proxy extension; use system proxy software like Surge/Proxier&lt;/li>
&lt;/ul>
&lt;h3 id="use-whistle-as-system-proxy">
&lt;a class="heading-anchor-link" href="#use-whistle-as-system-proxy">Use Whistle as system proxy&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="use-whistle-as-system-proxy"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I wrapped a tool to set Whistle as the system proxy to support apps like Safari.&lt;/p>
&lt;p>Run the following commands as needed; success output means it&amp;rsquo;s set.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Set system proxy&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npx @stacker/whistle.globalproxy &lt;span class="nb">set&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Custom host/port&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npx @stacker/whistle.globalproxy &lt;span class="nb">set&lt;/span> --port &lt;span class="m">8899&lt;/span> --host 127.0.0.1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Clear system proxy&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npx @stacker/whistle.globalproxy clear
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Note: system proxy is unique. If you already have one, this will override it.&lt;/p>
&lt;h3 id="verify-proxy-success">
&lt;a class="heading-anchor-link" href="#verify-proxy-success">Verify proxy success&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="verify-proxy-success"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>There are many ways: visit a site and check the certificate shows Whistle; or check Whistle&amp;rsquo;s Network tab for entries.&lt;/p>
&lt;p>After these steps, you can proxy all browser requests through Whistle.&lt;/p>
&lt;h2 id="socks-proxy">
&lt;a class="heading-anchor-link" href="#socks-proxy">SOCKS proxy&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="socks-proxy"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you only need to proxy HTTP sites, configure Whistle HTTP proxy. If you need SOCKS, enable SocksServer. For browser extensions, requests are HTTP/WebSocket, so HTTP is enough.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-09-25-174308.jpeg"
alt="https://static.1991421.cn/2022/2022-09-25-174308.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="whistle-proxy">
&lt;a class="heading-anchor-link" href="#whistle-proxy">Whistle proxy&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="whistle-proxy"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Whistle is just a proxy service. It does not take over system or app proxies by default, so you can mix and match. I previously wrote &lt;a href="https://1991421.cn/2021/09/30/ea60c0ab/" target="_blank" rel="noopener">Surge + Whistle&lt;/a>, but Surge has a learning curve. If you only need browser proxy, the extension is enough. If you want other apps (terminal, etc.) to use Whistle, you need additional setup (e.g., shell proxy env vars).&lt;/p>
&lt;h2 id="mobile-proxy">
&lt;a class="heading-anchor-link" href="#mobile-proxy">Mobile proxy&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mobile-proxy"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Sometimes you need a phone to access a site and capture traffic on a PC. Solution: connect the phone to the PC&amp;rsquo;s Whistle proxy.&lt;/p>
&lt;ol>
&lt;li>Set proxy on phone network.&lt;/li>
&lt;li>Scan to download Whistle cert, install and trust it.&lt;/li>
&lt;li>Visit the site and confirm requests appear in Whistle Network.&lt;/li>
&lt;/ol>
&lt;h2 id="configuration-tips">
&lt;a class="heading-anchor-link" href="#configuration-tips">Configuration tips&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="configuration-tips"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="modify-request-ua-header">
&lt;a class="heading-anchor-link" href="#modify-request-ua-header">Modify request UA header&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="modify-request-ua-header"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Add rule:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">https://1991421.cn ua://{browser_ie10_ua}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Configure browser_ie10_ua in values:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.2; .NET4.0C; .NET4.0E)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="modify-windownavigatoruseragent">
&lt;a class="heading-anchor-link" href="#modify-windownavigatoruseragent">Modify window.navigator.userAgent&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="modify-windownavigatoruseragent"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Some logic like compatibility pages can be simulated by programmatically changing UA.&lt;/p>
&lt;p>Add rule:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">https://1991421.cn jsPrepend://{ie11_js_ua}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Configure ie11_js_ua in values:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">window&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">navigator&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">__defineGetter__&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;userAgent&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">function&lt;/span>&lt;span class="p">(){&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s2">&amp;#34;Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0; rv:11.0) like Gecko&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// customized user agent
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="remote-address">
&lt;a class="heading-anchor-link" href="#remote-address">Remote Address&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="remote-address"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-07-20-224825.jpeg"
alt="https://static.1991421.cn/2023/2023-07-20-224825.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>After routing through Whistle, the remote address shows as &lt;code>Remote Address: [::1]:8899&lt;/code>. To see the original Remote Address, add this rule:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">* resHeaders://`x-remote-address=${serverIp}`
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Establishing a Chinese Blog Translation Workflow</title><link>https://en.1991421.cn/2022/05/02/401d465/</link><pubDate>Mon, 02 May 2022 23:12:49 +0800</pubDate><guid>https://en.1991421.cn/2022/05/02/401d465/</guid><description>&lt;blockquote>
&lt;p>I&amp;rsquo;ve been trying to translate Chinese blog posts into English and publish them on the Medium platform. Currently, I manually select articles and give them to my girlfriend for translation, then she gives them back to me for publishing. The whole process is still inefficient, so I&amp;rsquo;m taking advantage of the holiday to optimize this workflow.&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>
&lt;p>Update and optimize the Chinese blog CI process&lt;/p>
&lt;ul>
&lt;li>Add an automated script to pull article MD source code, so there&amp;rsquo;s always a copy of the latest Chinese blog on the VPS&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Deploy a web service for blog source files on the VPS&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Using local-web-server here&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Also add some security measures with auth configuration&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">ws --auth.user root --auth.pass 123456
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>​ This way you can directly access all MD article source code via web, and ws also provides simple search highlighting, which is basically sufficient&lt;/p>
&lt;ol start="3">
&lt;li>Manually save source files locally&lt;/li>
&lt;li>Send to publisher after translation&lt;/li>
&lt;li>Manually commit to English repo, auto-deployment&lt;/li>
&lt;/ol>
&lt;p>This is the first phase of the workflow. In the future, I&amp;rsquo;ll address the issue of automatic publishing after translation based on needs.&lt;/p></description></item><item><title>Bought an Xbox Series S</title><link>https://en.1991421.cn/2022/05/01/xbox-series-s/</link><pubDate>Sun, 01 May 2022 21:15:47 +0800</pubDate><guid>https://en.1991421.cn/2022/05/01/xbox-series-s/</guid><description>&lt;blockquote>
&lt;p>With the pandemic keeping me at home, I picked up an Xbox Series S to beat the boredom. Here&amp;rsquo;s how the purchase and setup went.&lt;/p>
&lt;/blockquote>
&lt;img src="https://static.1991421.cn/2022/2022-05-01-214505.jpeg" style="zoom:33%;" />
&lt;h2 id="prerequisites">
&lt;a class="heading-anchor-link" href="#prerequisites">Prerequisites&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="prerequisites"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Register an Outlook account—it&amp;rsquo;s your Microsoft services login.&lt;/li>
&lt;li>Make sure your TV or monitor is ready and supports external audio or has speakers.&lt;/li>
&lt;li>Install the Xbox mobile app; you&amp;rsquo;ll need it later to pair with the console.&lt;/li>
&lt;/ol>
&lt;h2 id="choosing-the-console">
&lt;a class="heading-anchor-link" href="#choosing-the-console">Choosing the Console&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="choosing-the-console"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I already own a Switch, which is great for casual games, but this time I wanted to play big-budget titles. The real options were down to PlayStation or Xbox, and then whether to go high-end or entry-level.&lt;/p>
&lt;p>Since I&amp;rsquo;m still a beginner and really wanted to play Microsoft&amp;rsquo;s exclusives—especially Halo—I chose the lower-tier Xbox Series S.&lt;/p>
&lt;p>Key specs of the XSS:&lt;/p>
&lt;ol>
&lt;li>It handles 2K output just fine.&lt;/li>
&lt;li>The 512 GB SSD fills up quickly, but with AAA games you won&amp;rsquo;t rotate through many at once.&lt;/li>
&lt;li>Supports external storage, so there&amp;rsquo;s an escape hatch if space gets tight.&lt;/li>
&lt;/ol>
&lt;p>Decision made, I ordered it right away. To avoid any surprises with the domestic market, I went with the Japanese model for about &lt;code>2100 RMB&lt;/code>. The box only includes one controller.&lt;/p>
&lt;!-- more -->
&lt;h2 id="xbox-game-pass-xgp">
&lt;a class="heading-anchor-link" href="#xbox-game-pass-xgp">Xbox Game Pass (XGP)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xbox-game-pass-xgp"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Once you have the console, you need games. Microsoft isn&amp;rsquo;t shy about investing here, so Game Pass is more than enough.&lt;/p>
&lt;p>Subscribe at: &lt;a href="https://www.xbox.com/zh-hk/xbox-game-pass#join" target="_blank" rel="noopener">https://www.xbox.com/zh-hk/xbox-game-pass#join&lt;/a>&lt;/p>
&lt;p>Keep a few things in mind:&lt;/p>
&lt;ol>
&lt;li>Even with Game Pass, &lt;code>not every game is included&lt;/code>. If it&amp;rsquo;s covered, you&amp;rsquo;ll see an install button. If you still see a price—discounted or not—you&amp;rsquo;ll need to pay separately.&lt;/li>
&lt;li>The first month is heavily discounted. I subscribed to the &lt;code>Hong Kong&lt;/code> region and paid &lt;code>10 HKD&lt;/code> for month one. After that it gets pricey, so if you&amp;rsquo;re just trying it out, subscribe, then manually cancel to avoid automatic renewal. Manage your subscription &lt;a href="https://account.microsoft.com/services/" target="_blank" rel="noopener">here&lt;/a>.&lt;/li>
&lt;li>If you&amp;rsquo;re only playing on console, pick the Console tier. The Core tier only includes multiplayer access.&lt;/li>
&lt;li>If you bought the wrong plan, don&amp;rsquo;t worry—you can upgrade to something like Ultimate and Microsoft will prorate the price.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-02-04-220822.jpeg"
alt="https://static.1991421.cn/2024/2024-02-04-220822.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="powering-on">
&lt;a class="heading-anchor-link" href="#powering-on">Powering On&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="powering-on"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Press the Xbox logo on the console or controller to turn it on.&lt;/li>
&lt;li>The controller takes &lt;code>two AA batteries&lt;/code>.&lt;/li>
&lt;li>Signing into Outlook on the Xbox is a bit clunky. I recommend choosing the &amp;ldquo;Use another device&amp;rdquo; option: the Xbox will display a code, and you can go to &lt;a href="https://www.microsoft.com/link" target="_blank" rel="noopener">https://www.microsoft.com/link&lt;/a> on your phone to enter it and sign in.&lt;/li>
&lt;/ol>
&lt;h3 id="connecting-to-the-tv">
&lt;a class="heading-anchor-link" href="#connecting-to-the-tv">Connecting to the TV&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="connecting-to-the-tv"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Once the console arrives, hook it up to your TV.&lt;/p>
&lt;p>I ran into an issue where audio wouldn&amp;rsquo;t play. The Xbox misdetected the connection as DVI even though the cable was HDMI.&lt;/p>
&lt;p>To fix it, go to Settings → Video Output → Video fidelity &amp;amp; overscan and manually select HDMI.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-05-01-213007.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>To make managing Game Pass easier, download the official app on Android or iOS.&lt;/p>
&lt;h2 id="first-impressions">
&lt;a class="heading-anchor-link" href="#first-impressions">First Impressions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="first-impressions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After a few hours of playtime, here are my takeaways:&lt;/p>
&lt;ol>
&lt;li>Compared with buying games individually, Game Pass is already a great deal.&lt;/li>
&lt;li>The Game Pass app is decent—you can view clips, screenshots, and use it as a remote.&lt;/li>
&lt;li>The Xbox hardware feels well-made, and the controller is excellent.&lt;/li>
&lt;/ol></description></item><item><title>Glob Patterns</title><link>https://en.1991421.cn/2022/03/19/glob/</link><pubDate>Sat, 19 Mar 2022 22:38:46 +0800</pubDate><guid>https://en.1991421.cn/2022/03/19/glob/</guid><description>&lt;blockquote>
&lt;p>I often encounter glob patterns at work, such as include configs in eslint/tsc, file filtering in shell, and IDE file masks. I never learned them systematically, so I used them inefficiently. I&amp;rsquo;m documenting them here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-03-19-232453.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="glob-vs-regex">
&lt;a class="heading-anchor-link" href="#glob-vs-regex">Glob vs regex&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="glob-vs-regex"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After reading some materials, here are my notes:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Glob is not regex, and metacharacters differ. For example, &lt;code>?&lt;/code> means a single character in glob, while in regex it means the previous token is optional.&lt;/p>
&lt;p>So you must distinguish glob and regex metacharacters.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Glob and regex are used differently. &lt;code>Regex is for text processing&lt;/code>, like searching in content, while &lt;code>glob is for file matching&lt;/code>. It is not that glob cannot be used for text, or regex cannot be used for files, but this is the common convention.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Regex is more powerful, while glob is concise.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>There are many glob syntax guides online, so I won&amp;rsquo;t list them here.&lt;/p>
&lt;h2 id="practice-glob">
&lt;a class="heading-anchor-link" href="#practice-glob">Practice glob&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="practice-glob"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The best way is practice, especially common wildcards like ** and ?.&lt;/p>
&lt;p>I recommend this site for testing patterns online:&lt;/p>
&lt;p>&lt;a href="https://globster.xyz/" target="_blank" rel="noopener">https://globster.xyz/&lt;/a>&lt;/p>
&lt;h2 id="file-masks">
&lt;a class="heading-anchor-link" href="#file-masks">File Masks&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="file-masks"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In WebStorm, a common feature is search with file masks. It turns out file masks are a subset of glob with extensions (comma for multiple patterns).&lt;/p>
&lt;p>So you can use &lt;code>*.css,*.less&lt;/code> to match multiple file types.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-03-19-233714.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Glob is like regex: not always high-frequency, but a basic skill. Practice and memorize.&lt;/p>
&lt;h2 id="resources">
&lt;a class="heading-anchor-link" href="#resources">Resources&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="resources"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://www.ruanyifeng.com/blog/2018/09/bash-wildcards.html" target="_blank" rel="noopener">https://www.ruanyifeng.com/blog/2018/09/bash-wildcards.html&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://github.com/whinc/whinc.github.io/issues/18" target="_blank" rel="noopener">Glob pattern matching tutorial&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://help.globalscape.com/help/awe/Task_Builder/File_Masks___Wildcards.html" target="_blank" rel="noopener">https://help.globalscape.com/help/awe/Task_Builder/File_Masks___Wildcards.html&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul></description></item><item><title>How to Use Keys and Certificates (Step-by-Step Guide)</title><link>https://en.1991421.cn/2022/03/09/9026dcd/</link><pubDate>Wed, 09 Mar 2022 18:49:05 +0800</pubDate><guid>https://en.1991421.cn/2022/03/09/9026dcd/</guid><description>&lt;h2 id="openssl">
&lt;a class="heading-anchor-link" href="#openssl">OpenSSL&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="openssl"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 版本信息&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ openssl version -a
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 性能测试&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ openssl speed
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="pem-basics">
&lt;a class="heading-anchor-link" href="#pem-basics">PEM Basics&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pem-basics"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">-----BEGIN &amp;lt;whatever&amp;gt;-----
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">data
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -----END &amp;lt;whatever&amp;gt;----
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>Stores certificates or private keys.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Each line is 64 characters.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>PEM is Base64-encoded DER.&lt;/p>
&lt;blockquote>
&lt;p>PEM or Privacy Enhanced Mail is a Base64 encoded DER certificate.&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;li>
&lt;p>DER/CER are binary encodings (cer typically omits the private key).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The first 32 characters of a PEM file are cosmetic; they don’t affect usage.&lt;/p>
&lt;/li>
&lt;/ul></description></item><item><title>Canvas Drawing with GIF Animation Issues</title><link>https://en.1991421.cn/2022/01/31/85c40c8/</link><pubDate>Mon, 31 Jan 2022 14:51:40 +0800</pubDate><guid>https://en.1991421.cn/2022/01/31/85c40c8/</guid><description>&lt;blockquote>
&lt;p>Recently, I&amp;rsquo;ve been working on a mini-program with a poster sharing feature. The basic approach is to draw images and text onto a poster Canvas, which also supports output as dataURL, making downloads simple. However, one type of image resource is GIF, which is a dynamic resource containing multiple frames. Testing shows that GIF resources work fine when drawing posters, but the question is: which frame does a GIF animation use when generating a static image, and how can we change this? Let me explore this during the holidays.&lt;/p>
&lt;/blockquote>
&lt;h2 id="canvasgetcontext2ddrawimage">
&lt;a class="heading-anchor-link" href="#canvasgetcontext2ddrawimage">canvas.getContext(&amp;lsquo;2d&amp;rsquo;).drawImage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="canvasgetcontext2ddrawimage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>This is the function used for drawing posters. Since each frame of a GIF might be different, I examined several typical GIFs and found through comparison that when drawing, the first frame of the GIF is used.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-31-151309.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>On Mac, you can use Preview to preview GIFs, and the displayed number represents the frame count.&lt;/p>
&lt;!-- more -->
&lt;h2 id="specifying-which-gif-frame-to-draw">
&lt;a class="heading-anchor-link" href="#specifying-which-gif-frame-to-draw">Specifying Which GIF Frame to Draw&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="specifying-which-gif-frame-to-draw"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Canvas or HTMLImageElement don&amp;rsquo;t provide this capability natively, but the third-party library &lt;code>libgif&lt;/code> can solve this problem.&lt;/p>
&lt;p>The main approach is to use the function &lt;code>superGifEl.move_to(50); superGifEl.pause();&lt;/code> to move to a specified frame, then stop playback to get the canvas in that context.&lt;/p>
&lt;p>Here&amp;rsquo;s a complete example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">canvas&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">document&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">getElementById&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;canvas&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">ctx&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">canvas&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">getContext&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;2d&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">parentEl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">document&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">createElement&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;div&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">parentEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">style&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">display&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;none&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">imgEl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">Image&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">60&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">45&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">imgEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">src&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;./5-160914192R4.gif&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">parentEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">appendChild&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">imgEl&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">superGifEl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">SuperGif&lt;/span>&lt;span class="p">({&lt;/span> &lt;span class="nx">gif&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">imgEl&lt;/span> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">superGifEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">load&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kd">function&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">superGifEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">move_to&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">superGifEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">pause&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">drawImageForGif&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;The number of frames in the gif:&amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">superGifEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get_length&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">function&lt;/span> &lt;span class="nx">drawImageForGif&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">canvas&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">width&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">imgEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">naturalWidth&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">canvas&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">height&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">imgEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">naturalHeight&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">superGifEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get_canvas&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="nx">toDataURL&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;image/png&amp;#39;&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">ctx&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">drawImage&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">superGifEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get_canvas&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">imgEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">naturalWidth&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">imgEl&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">naturalHeight&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">function&lt;/span> &lt;span class="nx">downloadURI&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">uri&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">name&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">var&lt;/span> &lt;span class="nx">link&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">document&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">createElement&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;a&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">link&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">download&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">name&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">link&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">href&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">uri&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">document&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">body&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">appendChild&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">link&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">link&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">click&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">document&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">body&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">removeChild&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">link&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">delete&lt;/span> &lt;span class="nx">link&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">function&lt;/span> &lt;span class="nx">download&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">downloadURI&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">canvas&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">toDataURL&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;image/png&amp;#39;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="s1">&amp;#39;wp.png&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="a-small-pitfall">
&lt;a class="heading-anchor-link" href="#a-small-pitfall">A Small Pitfall&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="a-small-pitfall"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The reason we need &lt;code>const parentEl = document.createElement('div');&lt;/code> is because libgif&amp;rsquo;s implementation involves using the parent element of the GIF resource. Since we&amp;rsquo;re using the Image constructor here rather than &lt;code>document.createElement&lt;/code>, there&amp;rsquo;s no parent element. To avoid console errors, we add a hidden parent element.&lt;/p>
&lt;h2 id="wechat-mini-program-component---painter">
&lt;a class="heading-anchor-link" href="#wechat-mini-program-component---painter">WeChat Mini Program Component - Painter&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wechat-mini-program-component---painter"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>WeChat mini programs support Canvas drawing, but the native Canvas APIs are still cumbersome to operate. For convenience, I use the &lt;a href="https://github.com/Kujiale-Mobile/Painter" target="_blank" rel="noopener">Painter&lt;/a> component.&lt;/p>
&lt;p>The Painter component supports image resources in URL format, and with SuperGif =&amp;gt; Canvas =&amp;gt; toDataURL, this problem is solved in mini programs.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>With the above solution, when sharing posters with GIF resources, you can flexibly control which frame to select.&lt;/p></description></item><item><title>US App Store Apple ID Payment Options</title><link>https://en.1991421.cn/2022/01/23/appleid/</link><pubDate>Sun, 23 Jan 2022 22:38:55 +0800</pubDate><guid>https://en.1991421.cn/2022/01/23/appleid/</guid><description>&lt;blockquote>
&lt;p>A US (or other non-mainland) Apple ID lets you download apps not available in the China store, but paid apps require a valid payment method. Without a US PayPal or US-issued Visa, Apple gift cards are the practical option. Here&amp;rsquo;s the workflow.&lt;/p>
&lt;/blockquote>
&lt;h2 id="gift-cards-are-region-locked">
&lt;a class="heading-anchor-link" href="#gift-cards-are-region-locked">Gift cards are region-locked&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="gift-cards-are-region-locked"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Because gift cards are tied to regions, they cannot be used across stores. If you want to fund a US account, you must buy the card from Apple’s US store.&lt;/p>
&lt;!-- more -->
&lt;h2 id="buying-a-gift-card">
&lt;a class="heading-anchor-link" href="#buying-a-gift-card">Buying a gift card&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="buying-a-gift-card"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Visit the &lt;a href="https://www.apple.com/shop/buy-giftcard/giftcard" target="_blank" rel="noopener">US Apple Store&lt;/a> and follow the steps. The purchaser and recipient can both be you.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Apple requires a &lt;strong>minimum of USD 10&lt;/strong>; the current range is &lt;strong>USD 10–2,000&lt;/strong>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Visa works for payment, and Apple does not validate the issuing country for this flow.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-23-224345.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The phone number can be a fake entry or your Google Voice number.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Delivery is not instant; expect the email within an hour. My recent orders arrived in about ten minutes.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-23-230240.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="redeeming-the-card">
&lt;a class="heading-anchor-link" href="#redeeming-the-card">Redeeming the card&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="redeeming-the-card"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When the email titled &lt;code>xxx sent you an Apple Gift Card&lt;/code> arrives, open the App Store and redeem it.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-23-224839.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>After the redemption confirmation, purchases will automatically draw from the balance.&lt;/p>
&lt;h2 id="hong-kong-apple-id--hang-seng-debit-card">
&lt;a class="heading-anchor-link" href="#hong-kong-apple-id--hang-seng-debit-card">Hong Kong Apple ID + Hang Seng debit card?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="hong-kong-apple-id--hang-seng-debit-card"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I also hold a Citic Hong Kong card and hoped it could fund my Hong Kong Apple ID. Turns out Hong Kong Apple IDs only accept credit cards, not stored-value/debit cards, so that path is closed. Gift cards remain the workaround.&lt;/p>
&lt;h2 id="tax-free-purchases">
&lt;a class="heading-anchor-link" href="#tax-free-purchases">Tax-free purchases&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tax-free-purchases"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If your account is tied to a taxable state, you will still be charged tax. To avoid it, you must change the region, but only when your balance is zero. If you have only a small amount left, contact support and ask them to clear it.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Gift cards aren’t perfect, but they’re simple and effective for solving US App Store payments, freeing you from the “free apps only” restriction.&lt;/p></description></item><item><title>Integrating Google AdSense</title><link>https://en.1991421.cn/2022/01/09/google-adsense/</link><pubDate>Sun, 09 Jan 2022 17:12:14 +0800</pubDate><guid>https://en.1991421.cn/2022/01/09/google-adsense/</guid><description>&lt;blockquote>
&lt;p>My blog has integrated Google AdSense. Although it doesn&amp;rsquo;t make money, it&amp;rsquo;s a virtuous process - the more articles I write and the better they get, naturally SEO improves, user traffic increases, and ads naturally generate income, and it&amp;rsquo;s 24/7.&lt;/p>
&lt;p>I found there&amp;rsquo;s not much introduction online about integrating Ads, so I&amp;rsquo;ll explain here&lt;/p>
&lt;/blockquote>
&lt;h2 id="google-adsensesearch-consoleanalytics">
&lt;a class="heading-anchor-link" href="#google-adsensesearch-consoleanalytics">Google AdSense/Search Console/Analytics&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="google-adsensesearch-consoleanalytics"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Google has these 3 services. Do you need to activate all of them? What are the differences? Let me explain.&lt;/p>
&lt;ol>
&lt;li>AdSense controls ad placement on websites to make money&lt;/li>
&lt;li>Search Console is basically a webmaster tool where you can submit sitemaps to Google for indexing, the purpose being SEO&lt;/li>
&lt;li>Analytics comprehensively analyzes your site - like what users, where they stay longer, etc. The data is more detailed and multi-dimensional.&lt;/li>
&lt;/ol>
&lt;p>For example, my blog doesn&amp;rsquo;t need such detailed analytics data, so AdSense/Search Console are sufficient. The reason I need Console is for SEO, thereby improving the probability of users finding my articles through search. With traffic, there are naturally opportunities to place ads and make money.&lt;/p>
&lt;!-- more -->
&lt;h2 id="google-adsense-registration">
&lt;a class="heading-anchor-link" href="#google-adsense-registration">Google AdSense Registration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="google-adsense-registration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Ad account is separate from the Google account itself, it just supports Google account SSO. Directly logging into AD will prompt that the Google account hasn&amp;rsquo;t registered for AD service, just choose sign up&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2023/2023-01-28-211131.jpeg"
alt="https://static.1991421.cn/2023/2023-01-28-211131.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="google-adsense-integration">
&lt;a class="heading-anchor-link" href="#google-adsense-integration">Google AdSense Integration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="google-adsense-integration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Follow the prompts for website integration, which will eventually add an ads.txt file.&lt;/li>
&lt;li>Confirm that adsbygoogle code has been integrated&lt;/li>
&lt;/ol>
&lt;img src="https://static.1991421.cn/2023/2023-07-15-121225.jpeg" alt="https://static.1991421.cn/2023/2023-07-15-121225.jpeg" style="zoom: 67%;" />
&lt;p>After correct integration, it takes about 1 hour before ads will display&lt;/p>
&lt;h2 id="search-console-integration">
&lt;a class="heading-anchor-link" href="#search-console-integration">Search Console Integration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="search-console-integration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>There are two ways to add sites: domain/URL. Domain will include all subdomains and the verification method is DNS record addition. URL only covers the target domain.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-17-233102.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Since I only want to add two domains and track them separately, I chose URL, then flexibly choose the method. For example, I chose HTML tag here, configure &lt;code>google_site_verification&lt;/code>, then select verify.&lt;/p>
&lt;h2 id="adsense-revenue-transfer-to-domestic-bank-cards">
&lt;a class="heading-anchor-link" href="#adsense-revenue-transfer-to-domestic-bank-cards">AdSense Revenue Transfer to Domestic Bank Cards&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="adsense-revenue-transfer-to-domestic-bank-cards"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>When Google Adsense account balance reaches $10, PIN code verification will be triggered. This means sending a PIN code via regular mail to the payee address in the publisher account. If verification isn&amp;rsquo;t completed within the specified period, ad display will be stopped.&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>
&lt;p>Check your mailbox for PIN code related emails - the Chinese title is &lt;code>Action needed: Please verify your payment address in AdSense&lt;/code>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-09-172732.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>PIN code can be received up to 4 times&lt;/code>, note that if you apply for a new PIN code but receive an old PIN code, it can still be used for valid verification&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Domestic addresses can&amp;rsquo;t receive the mail, so you need to wait until all 4 attempts fail, then proceed with online verification&lt;/p>
&lt;p>&lt;a href="https://support.google.com/adsense/troubleshooter/1094206?hl=en&amp;amp;visit_id=637492546905021027-2584291833&amp;amp;rd=1#ts=1106772%2C1106778%2C1106795" target="_blank" rel="noopener">https://support.google.com/adsense/troubleshooter/1094206?hl=en&amp;visit_id=637492546905021027-2584291833&amp;rd=1#ts=1106772%2C1106778%2C1106795&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="online-verification">
&lt;a class="heading-anchor-link" href="#online-verification">Online Verification&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="online-verification"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-09-172426.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="bank-card-cannot-accept-remittance">
&lt;a class="heading-anchor-link" href="#bank-card-cannot-accept-remittance">Bank Card Cannot Accept Remittance&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bank-card-cannot-accept-remittance"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Taking China Merchants Bank as an example, starting from May 2024, overseas remittance receipts will find $5 missing. This fee is not a handling fee charged by China Merchants Bank but a deduction by the remittance correspondent bank.&lt;/p>
&lt;p>For related issues, there&amp;rsquo;s &lt;a href="https://www.v2ex.com/t/1052468" target="_blank" rel="noopener">discussion on v2ex&lt;/a>&lt;/p>
&lt;h2 id="how-to-close-adsense">
&lt;a class="heading-anchor-link" href="#how-to-close-adsense">How to Close Adsense&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-to-close-adsense"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Considering that ads affect webpage loading speed and impact user browsing experience, if you don&amp;rsquo;t like ad placement services, you can manually close it. The closing address is Console - Settings - Account, close account.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>If you want to enable it later, visit the console and the webpage will prompt to reactivate the account, just click enable.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since I haven&amp;rsquo;t used domestic ad services, I can&amp;rsquo;t make horizontal comparisons, but currently I think Google AdSense is a relatively simple and professional service.&lt;/p></description></item><item><title>Tools of the Year: 2021 Gear Review</title><link>https://en.1991421.cn/2022/01/09/2021/</link><pubDate>Sun, 09 Jan 2022 16:43:33 +0800</pubDate><guid>https://en.1991421.cn/2022/01/09/2021/</guid><description>&lt;blockquote>
&lt;p>Great tools need to be refined and occasionally replaced. 2021 is over, so it&amp;rsquo;s time to review the hardware and software additions I made this year and how they&amp;rsquo;ve enhanced my workflow.&lt;/p>
&lt;/blockquote>
&lt;h2 id="iphone-12">
&lt;a class="heading-anchor-link" href="#iphone-12">iPhone 12&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="iphone-12"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in &lt;strong>early May&lt;/strong>. I&amp;rsquo;ve really enjoyed using it, particularly the Face ID integration and the synergy with my Apple Watch.&lt;/p>
&lt;!-- more -->
&lt;h3 id="favorite-features">
&lt;a class="heading-anchor-link" href="#favorite-features">Favorite Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="favorite-features"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Face ID&lt;/strong>: The recognition speed is solid, though it still fails occasionally. I hope future versions are even more precise.&lt;/li>
&lt;li>&lt;strong>Apple Watch Unlock&lt;/strong>: Being able to unlock my phone while wearing a mask (via AW) is a fantastic quality-of-life improvement.&lt;/li>
&lt;li>&lt;strong>Shortcuts&lt;/strong>: I use these for automating SMS, checking mobile balances, and one-tap health code scanning. While some apps limit full automation, it’s still incredibly useful.&lt;/li>
&lt;/ol>
&lt;h2 id="electric-heating-faucet-a-lifesaver-for-older-apartments">
&lt;a class="heading-anchor-link" href="#electric-heating-faucet-a-lifesaver-for-older-apartments">Electric Heating Faucet (A Lifesaver for Older Apartments)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="electric-heating-faucet-a-lifesaver-for-older-apartments"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I live in an older building where the kitchen isn&amp;rsquo;t connected to the central water heater. I bought a Supor electric heating faucet in &lt;strong>December&lt;/strong> for &lt;strong>179 RMB&lt;/strong>. It’s been a great addition.&lt;/p>
&lt;p>&lt;strong>Key Notes:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>The water gets warm but not scalding hot.&lt;/li>
&lt;li>Be careful with installation; ensure the faucet specs match your sink.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-12-02-222525.jpeg"
alt="Electric Heating Faucet"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="typora">
&lt;a class="heading-anchor-link" href="#typora">Typora&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="typora"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The &lt;strong>$14.99&lt;/strong> one-time purchase is very reasonable. It supports up to three devices.&lt;/p>
&lt;p>&lt;strong>Pros:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Excellent keyboard shortcuts (e.g., &lt;code>⌘2&lt;/code> for H2 headers).&lt;/li>
&lt;li>Works perfectly with iCloud for multi-device document syncing.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Cons:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Doesn&amp;rsquo;t sync configurations/themes via iCloud.&lt;/li>
&lt;li>Occasional performance lags or hangs.&lt;/li>
&lt;/ol>
&lt;h2 id="apple-tv-atv-5">
&lt;a class="heading-anchor-link" href="#apple-tv-atv-5">Apple TV (ATV 5)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-tv-atv-5"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in &lt;strong>November&lt;/strong> for &lt;strong>820 CNY&lt;/strong>. While Chinese streaming services have TV apps, they are expensive and often have restricted libraries. The ATV via AirPlay is a much better solution.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-11-06-173748.jpeg"
alt="Apple TV Setup"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Pros:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Access to YouTube (requires router-level proxy).&lt;/li>
&lt;li>Connects to my NAS for a home theater experience.&lt;/li>
&lt;li>AirPlay from iPhone/iPad works flawlessly for streaming services like Tencent Video.&lt;/li>
&lt;li>The classic Apple experience: smooth, professional, and reliable.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Cons:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>A mainland China Apple ID provides almost no services. You need a US or other regional ID to download most useful apps.&lt;/li>
&lt;/ul>
&lt;h2 id="wechat-reading">
&lt;a class="heading-anchor-link" href="#wechat-reading">WeChat Reading&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wechat-reading"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I only started using this seriously this year and found it to be excellent.&lt;/p>
&lt;p>&lt;strong>Pros:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Massive collection of Chinese books.&lt;/li>
&lt;li>Great user experience and typography.&lt;/li>
&lt;li>Social features that actually encourage reading.&lt;/li>
&lt;li>&amp;ldquo;Free&amp;rdquo; model: By reading regularly, you can earn &amp;ldquo;Unlimited Cards,&amp;rdquo; allowing you to read without a paid subscription while building a consistent habit.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Cons:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Like many domestic apps, the social features can sometimes feel like &amp;ldquo;noise.&amp;rdquo;&lt;/li>
&lt;li>The selection of foreign language books is limited compared to services like O&amp;rsquo;Reilly.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After several years of refining my hardware and software ecosystem, it has reached a state of relative stability. The focus now is simply on using these tools effectively to maintain high quality and efficiency in my work and life.&lt;/p></description></item><item><title>2021 Year-End Review</title><link>https://en.1991421.cn/2022/01/09/2021/</link><pubDate>Sun, 09 Jan 2022 12:37:49 +0800</pubDate><guid>https://en.1991421.cn/2022/01/09/2021/</guid><description>&lt;blockquote>
&lt;p>2021 is over. Looking back at the past twelve months, it&amp;rsquo;s time for my annual summary.&lt;/p>
&lt;/blockquote>
&lt;h2 id="career-transition">
&lt;a class="heading-anchor-link" href="#career-transition">Career Transition&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="career-transition"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In May of this year, I changed jobs after 1.5 years at my previous company. While I&amp;rsquo;m not someone who enjoys frequent job-hopping for salary bumps, I stand by the explanation I gave HR: &amp;ldquo;The wasted years early in my career taught me a hard lesson—if you&amp;rsquo;re unhappy and feel your time is being squandered, move on without overthinking it.&amp;rdquo;&lt;/p>
&lt;p>Looking back at those 1.5 years, I did grow technically, but the environment provided too few external challenges. Overall, my rate of growth was lower than I desired.&lt;/p>
&lt;!-- more -->
&lt;h2 id="the-new-role">
&lt;a class="heading-anchor-link" href="#the-new-role">The New Role&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-new-role"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since joining my new company in May, I&amp;rsquo;ve observed several key differences in the environment:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Maturity&lt;/strong>: The IT infrastructure is incredibly mature, the organizational structure is clear, and IT carries significant weight within the company. There are always resources to draw from and experts to consult.&lt;/li>
&lt;li>&lt;strong>Talent Density&lt;/strong>: The caliber of my teammates has noticeably improved. One of the best ways to measure your own growth is by the quality of the people and environment surrounding you.&lt;/li>
&lt;li>&lt;strong>Opportunities&lt;/strong>: Working at a major firm brings more resources and, consequently, more challenges. In just six months, I&amp;rsquo;ve worked on Mini Programs, Chrome extensions, CLI tools, scaffolding templates, and component documentation. The variety of roles—from UX designers to blockchain experts—makes cross-disciplinary learning easy.&lt;/li>
&lt;/ol>
&lt;h2 id="growth--contributions">
&lt;a class="heading-anchor-link" href="#growth--contributions">Growth &amp;amp; Contributions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="growth--contributions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="open-source">
&lt;a class="heading-anchor-link" href="#open-source">Open Source&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="open-source"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Since 2020, open source has been a major pillar of my personal output, and the returns have been steadily increasing.&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/alanhe421/alfred-workflows" target="_blank" rel="noopener">&lt;strong>Alfred Workflows&lt;/strong>&lt;/a>: Developed &lt;strong>10+&lt;/strong> new workflows, bringing the total to &lt;strong>32&lt;/strong> with &lt;strong>147 stars&lt;/strong>. This growth proves they solve real needs. As a daily user myself, value drives my continued development.&lt;/li>
&lt;li>&lt;a href="https://github.com/alanhe421/alfred-utils" target="_blank" rel="noopener">&lt;strong>Alfred SDK/CLI&lt;/strong>&lt;/a>: Created a scaffolding tool to streamline the development of new workflows.&lt;/li>
&lt;li>&lt;a href="https://github.com/alanhe421/webpack-replace-plugin" target="_blank" rel="noopener">&lt;strong>webpack-replace-plugin&lt;/strong>&lt;/a>: Developed an AST-based string replacement plugin to solve specific bundling issues at work.&lt;/li>
&lt;li>&lt;a href="https://github.com/alanhe421/chrome-extension-react-typescript-boilerplate" target="_blank" rel="noopener">&lt;strong>chrome-extension-react-typescript-boilerplate&lt;/strong>&lt;/a>: Frustrated by the lack of a good starter kit, I refined a template for building Chrome extensions with React and TypeScript.&lt;/li>
&lt;li>&lt;a href="https://github.com/alanhe421/codetracker-wxapp" target="_blank" rel="noopener">&lt;strong>codetracker-wxapp&lt;/strong>&lt;/a>: Built a WeChat Mini Program client for WakaTime to track my coding stats on the go and share them with friends.&lt;/li>
&lt;li>&lt;a href="https://github.com/alanhe421/repo-star-count-action" target="_blank" rel="noopener">&lt;strong>repo-star-count-action&lt;/strong>&lt;/a>: A GitHub Action to track repository star statistics for use in CI workflows.&lt;/li>
&lt;/ul>
&lt;p>Beyond personal satisfaction and community contribution, open source has a practical perk: it saves money. My active projects earned me free licenses for &lt;strong>JetBrains&lt;/strong> and &lt;strong>1Password&lt;/strong>, saving me hundreds of yuan annually.&lt;/p>
&lt;h3 id="blogging">
&lt;a class="heading-anchor-link" href="#blogging">Blogging&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="blogging"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>I wrote &lt;strong>108&lt;/strong> articles this year, bringing my lifetime total to &lt;strong>445&lt;/strong>. I&amp;rsquo;m proud of this consistency and plan to keep it up.&lt;/li>
&lt;li>I experimented with &lt;strong>Medium&lt;/strong>. While the response was good, withdrawing earnings to a Chinese account is cumbersome. Now that I have a Hong Kong bank card, I may re-explore this as a viable monetization path.&lt;/li>
&lt;li>In terms of direct blog monetization, referral links brought in about &lt;strong>$80&lt;/strong>. While small compared to server costs, it confirmed the value of traffic. Google AdSense only yields a few dollars a year, but it&amp;rsquo;s a positive feedback loop that encourages higher quality and quantity.&lt;/li>
&lt;/ul>
&lt;h3 id="wechat-official-account">
&lt;a class="heading-anchor-link" href="#wechat-official-account">WeChat Official Account&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wechat-official-account"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I operate &amp;ldquo;Alfred Road to Refinement.&amp;rdquo; Alfred is a niche topic, and my updates are infrequent, resulting in &lt;strong>45&lt;/strong> followers. While I get positive feedback, &amp;ldquo;knowledge tipping&amp;rdquo; is rare in the current domestic climate. Once the audience grows, I&amp;rsquo;ll consider advertising.&lt;/p>
&lt;h2 id="personal--lifestyle">
&lt;a class="heading-anchor-link" href="#personal--lifestyle">Personal &amp;amp; Lifestyle&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="personal--lifestyle"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="learning">
&lt;a class="heading-anchor-link" href="#learning">Learning&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="learning"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>WeChat Reading&lt;/strong>: I&amp;rsquo;ve become a fan of this platform and read several books this year (e.g., &lt;em>How the Network Connects&lt;/em>, &lt;em>Simple and Usable&lt;/em>, &lt;em>Half-Hour Manga&lt;/em>, &lt;em>Docker&lt;/em>). My strategy going forward is WeChat Reading for Chinese content, O&amp;rsquo;Reilly for English technical material, and MarginNote for offline PDF study.&lt;/li>
&lt;li>&lt;strong>Geek Time&lt;/strong>: I used this heavily during my job transition. Courses on frontend fundamentals provided great value during my commute.&lt;/li>
&lt;/ol>
&lt;h3 id="tools">
&lt;a class="heading-anchor-link" href="#tools">Tools&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tools"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>iPhone 12&lt;/strong>: Upgraded from an 8 Plus. I love Face ID, though I’ve realized I prefer a larger screen. My next upgrade will definitely be a Max model.&lt;/li>
&lt;li>&lt;strong>Numbers&lt;/strong>: I moved my financial tracking to Apple Numbers. Dedicated budgeting apps are often either intrusive or insecure. Numbers is simple, private, and effective.&lt;/li>
&lt;li>&lt;strong>Apple TV&lt;/strong>: A fantastic addition for home entertainment via AirPlay.&lt;/li>
&lt;li>&lt;strong>Typora&lt;/strong>: Even though it&amp;rsquo;s now a paid app, it&amp;rsquo;s so good that I didn&amp;rsquo;t hesitate to purchase a license. It’s my primary tool for blog drafting.&lt;/li>
&lt;/ul>
&lt;h2 id="travel">
&lt;a class="heading-anchor-link" href="#travel">Travel&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="travel"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Despite the pandemic, I managed two trips with my girlfriend: &lt;strong>Inner Mongolia&lt;/strong> in May and &lt;strong>Qingdao&lt;/strong> in September. Traveling is a great way to recharge and gain perspective on how others live. I hope to increase this to 3+ trips per year in the future.&lt;/p>
&lt;h2 id="major-milestones-marriage--housing">
&lt;a class="heading-anchor-link" href="#major-milestones-marriage--housing">Major Milestones: Marriage &amp;amp; Housing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="major-milestones-marriage--housing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Given our ages and long-term plans, we&amp;rsquo;ve started planning for marriage and buying a home in 2022. This will be the primary focus of the coming year, requiring a continued commitment to frugal living and saving.&lt;/p>
&lt;h2 id="other-achievements">
&lt;a class="heading-anchor-link" href="#other-achievements">Other Achievements&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other-achievements"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Health Insurance&lt;/strong>: I finally started using the supplemental health insurance provided by my company. After five hospital visits this year for minor issues, I realized how much I had been overpaying by not utilizing these benefits earlier. In one case, a 50 CNY bill was reduced to just 1 CNY after insurance.&lt;/li>
&lt;li>&lt;strong>Hong Kong Bank Card&lt;/strong>: One of the benefits of working for a large firm is access to better resources. After several months of processing, I finally secured a HK bank card. This makes managing a HK Apple ID and trading international stocks much simpler.&lt;/li>
&lt;/ul>
&lt;h2 id="2022-goals">
&lt;a class="heading-anchor-link" href="#2022-goals">2022 Goals&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2022-goals"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Get married and purchase a home.&lt;/li>
&lt;li>Reach the next level in my professional career.&lt;/li>
&lt;li>Double the quality and quantity of my open-source output.&lt;/li>
&lt;li>Begin monetizing my personal products (Mini Programs/Official Account).&lt;/li>
&lt;li>Establish a functional earnings workflow for Medium.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As I get older, I find myself becoming more pragmatic. I worry about becoming the &amp;ldquo;jaded veteran&amp;rdquo; or the &amp;ldquo;utilitarian&amp;rdquo; I once disliked. Regular self-reflection and a commitment to continuous self-improvement are my best defenses. Here&amp;rsquo;s to a productive 2022!&lt;/p></description></item><item><title>How to Use WakaTime (Step-by-Step Guide)</title><link>https://en.1991421.cn/2022/01/03/wakatime/</link><pubDate>Mon, 03 Jan 2022 21:46:03 +0800</pubDate><guid>https://en.1991421.cn/2022/01/03/wakatime/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>WakaTime&lt;/strong> is a fully automated time-tracking tool. It relies on plugins for many IDEs and text editors to visualize the time you spend coding, helping you understand exactly what you did during those hours.&lt;/p>
&lt;/blockquote>
&lt;h2 id="getting-started">
&lt;a class="heading-anchor-link" href="#getting-started">Getting Started&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="getting-started"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Visit &lt;a href="https://wakatime.com/login" target="_blank" rel="noopener">https://wakatime.com/login&lt;/a> and sign up for an account.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Go to &lt;a href="https://wakatime.com/settings/account" target="_blank" rel="noopener">https://wakatime.com/settings/account&lt;/a> and copy your API key.&lt;/p>
&lt;!-- more -->
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-03-220831.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Install the WakaTime plugin in WebStorm/Visual Studio Code (and other editors), then enter your &lt;code>API key&lt;/code>.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-03-220910.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>From then on, coding activity in those apps will be tracked. Visit WakaTime to view your stats.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>​&lt;/p>
&lt;p>&lt;em>If possible, use a proxy when accessing WakaTime for faster speed.&lt;/em>&lt;/p>
&lt;h2 id="wakatime-client--mini-program">
&lt;a class="heading-anchor-link" href="#wakatime-client--mini-program">WakaTime Client — Mini Program&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wakatime-client--mini-program"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>To make it easier to view the charts, I built a mini program over the weekend.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-01-03-232041.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>It mainly does two things:&lt;/p>
&lt;ol>
&lt;li>Proxies the WakaTime API service. My VPS is in Japan, so it’s not super fast yet, but it’s much better than accessing WakaTime directly.&lt;/li>
&lt;li>Provides visualizations based on the API + mini program.&lt;/li>
&lt;/ol>
&lt;h3 id="todo">
&lt;a class="heading-anchor-link" href="#todo">TODO&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="todo"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Add scheduled reminders when I exceed goals—less grindy and more humane. That will be implemented later; flag planted.&lt;/p></description></item><item><title>WeCom (Enterprise WeChat) Bots Explained (Simple Guide)</title><link>https://en.1991421.cn/2021/12/10/wecom-bot-intro/</link><pubDate>Fri, 10 Dec 2021 20:54:38 +0800</pubDate><guid>https://en.1991421.cn/2021/12/10/wecom-bot-intro/</guid><description>&lt;blockquote>
&lt;p>In work, WeCom (Enterprise WeChat) is our collaboration tool, and CI mechanisms are well-established in our company. For notification purposes, we often use it for instant feedback.&lt;/p>
&lt;p>Recently I&amp;rsquo;ve been involved in integrating some projects and learned about the WeCom API, so here&amp;rsquo;s an explanation of bots.&lt;/p>
&lt;/blockquote>
&lt;p>Strictly speaking, we can create two types of bots:&lt;/p>
&lt;ol>
&lt;li>Group Bots&lt;/li>
&lt;li>Regular Account Bots&lt;/li>
&lt;/ol>
&lt;!-- more -->
&lt;h2 id="group-bots">
&lt;a class="heading-anchor-link" href="#group-bots">Group Bots&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="group-bots"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Requires an administrator to create in the group, obtaining a webhook address&lt;/li>
&lt;li>Usage: Send request messages normally according to &lt;a href="https://work.weixin.qq.com/api/doc/90000/90136/91770" target="_blank" rel="noopener">API&lt;/a> requirements&lt;/li>
&lt;li>During testing, you can use curl commands or Postman for experimentation.&lt;/li>
&lt;/ol>
&lt;h2 id="regular-account-bots">
&lt;a class="heading-anchor-link" href="#regular-account-bots">Regular Account Bots&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="regular-account-bots"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Sometimes we want bots to send direct messages or perform more complex interactive operations. This can be achieved by calling APIs with a regular WeCom account.&lt;/p>
&lt;ol>
&lt;li>Register a WeCom account&lt;/li>
&lt;li>Call the &lt;a href="https://work.weixin.qq.com/api/doc/90000/90135/91039" target="_blank" rel="noopener">API&lt;/a> to obtain an access_token, then use it to send messages, create groups, etc.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Different approaches have different capabilities. For example, currently group bots can&amp;rsquo;t send messages with interactive buttons. Choose the solution that fits your needs.&lt;/li>
&lt;li>Personally, I think WeCom&amp;rsquo;s API is not as good as Telegram&amp;rsquo;s, but in the domestic Chinese environment, its ecosystem advantage is huge, so&amp;hellip; we have to use it.&lt;/li>
&lt;li>I hope WeChat will also open up its API&amp;hellip; not sure if that will happen.&lt;/li>
&lt;/ol></description></item><item><title>Getting Apple TV: It has a learning curve, but it's really good</title><link>https://en.1991421.cn/2021/11/06/e35f45/</link><pubDate>Sat, 06 Nov 2021 17:25:08 +0800</pubDate><guid>https://en.1991421.cn/2021/11/06/e35f45/</guid><description>&lt;blockquote>
&lt;p>During the 618 shopping festival, a friend recently asked me if it&amp;rsquo;s necessary to buy an Apple TV (ATV). I strongly recommend it! I need to admit that ATV has some usage barriers, but it&amp;rsquo;s really great—the experience completely beats domestic streaming boxes. Today, I&amp;rsquo;ll just write an article to share my experience using it.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-11-06-173748.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="purchase-motivation">
&lt;a class="heading-anchor-link" href="#purchase-motivation">Purchase Motivation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchase-motivation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Although my home TV is a smart TV, the operating system is very sluggish with all kinds of annoying ads, and the remote control is inconvenient. I&amp;rsquo;ve bought several Xiaomi boxes before but was not satisfied with any of them. So I decided to just buy an Apple TV—after all, it&amp;rsquo;s part of Apple&amp;rsquo;s ecosystem, and the experience shouldn&amp;rsquo;t be bad.&lt;/p>
&lt;p>In the end, I bought an Apple TV 5th generation 4K 64GB &lt;code>A1842&lt;/code> on Xianyu (a Chinese second-hand marketplace) for &lt;code>820 CNY&lt;/code>. After using it for a few days, the experience has been very good.&lt;/p>
&lt;p>Note: Currently, the Apple TV 7th generation is out, but models from the 5th generation onwards are all 4K. Buy according to your needs; the principle is to buy new if you can, but older models work too.&lt;/p>
&lt;h2 id="purchase-advice">
&lt;a class="heading-anchor-link" href="#purchase-advice">Purchase Advice&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchase-advice"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;code>US version is the best&lt;/code>. The Hong Kong version has a British-style plug and requires a converter. There is no Chinese mainland version of Apple TV.&lt;/li>
&lt;li>I personally think TV devices have a very low update frequency and the configuration is sufficient. You don&amp;rsquo;t need the latest model—just get what&amp;rsquo;s within your budget and meets your needs. Of course, models before the 5th generation are not recommended.&lt;/li>
&lt;/ol>
&lt;h2 id="some-barriers-to-entry">
&lt;a class="heading-anchor-link" href="#some-barriers-to-entry">Some Barriers to Entry&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="some-barriers-to-entry"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Apple TV isn&amp;rsquo;t very popular in China, and I think the biggest issue is the usage barriers.&lt;/p>
&lt;ol>
&lt;li>You need an &lt;code>international Apple ID&lt;/code>. If you need to pay for some apps in the future, you&amp;rsquo;ll also need to buy gift cards to solve payment issues.
&lt;ul>
&lt;li>When logging in with a Chinese mainland Apple ID, the App Store won&amp;rsquo;t be available, and the main usable feature is just AirPlay.&lt;/li>
&lt;li>A US Apple ID cannot enable Chinese Siri unless it&amp;rsquo;s for regions like Taiwan. However, Siri is very weak, so it&amp;rsquo;s not a big loss.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Network issues need to be solved by yourself.&lt;/li>
&lt;li>You need to have an iPad/iPhone or other Apple devices to solve input operation problems, such as logging in with passwords. Therefore, if you don&amp;rsquo;t have other Apple ecosystem devices, there&amp;rsquo;s no need to buy an Apple TV.&lt;/li>
&lt;/ol>
&lt;h2 id="accessories">
&lt;a class="heading-anchor-link" href="#accessories">Accessories&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="accessories"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>ATV accessories are relatively simple.&lt;/p>
&lt;ol>
&lt;li>Apple TV remote control sleeve, Apple TV protective case, remote control silicone sleeve.&lt;/li>
&lt;/ol>
&lt;p>I personally don&amp;rsquo;t recommend buying a protective sleeve for the set-top box.&lt;/p>
&lt;h2 id="setup-recommendations">
&lt;a class="heading-anchor-link" href="#setup-recommendations">Setup Recommendations&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="setup-recommendations"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="recommended-apps-to-install">
&lt;a class="heading-anchor-link" href="#recommended-apps-to-install">Recommended Apps to Install&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="recommended-apps-to-install"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The main apps I currently use are:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>YouTube (YT)&lt;/p>
&lt;ul>
&lt;li>Recommended to purchase a Premium membership.&lt;/li>
&lt;li>The TV version doesn&amp;rsquo;t require a separate payment, which is much better than domestic platforms like iQiyi and Tencent Video—it&amp;rsquo;s much more honest.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Infuse&lt;/p>
&lt;ul>
&lt;li>Accesses local NAS resources.&lt;/li>
&lt;li>Alibaba Cloud Disk is great; I recommend using them together.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Miao&lt;/p>
&lt;ul>
&lt;li>A third-party client for Bilibili.&lt;/li>
&lt;li>Paid app, $5.99 in the US App Store.&lt;/li>
&lt;li>If you can&amp;rsquo;t find it in non-Chinese App Stores, pay attention to the re-listing time to purchase. Price: $6. More information: &lt;a href="https://paladinfeng.notion.site/140462eaa3134ff68909102cb2b37e32" target="_blank" rel="noopener">https://paladinfeng.notion.site/140462eaa3134ff68909102cb2b37e32&lt;/a>. Official Telegram channel: &lt;a href="https://t.me/miaoproject" target="_blank" rel="noopener">https://t.me/miaoproject&lt;/a>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://apps.apple.com/us/app/iplaytv-iptv-m3u-player/id1072226801" target="_blank" rel="noopener">iPlayTV&lt;/a>&lt;/p>
&lt;ul>
&lt;li>Paid app, $5.99 in the US App Store.&lt;/li>
&lt;li>Views live TV channels like CCTV, requires manual addition of live broadcast sources.
&lt;ul>
&lt;li>
&lt;ol>
&lt;li>Free sources: such as &lt;a href="https://github.com/YueChan/Live/tree/main" target="_blank" rel="noopener">https://github.com/YueChan/Live/tree/main&lt;/a>.&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>
&lt;ol start="2">
&lt;li>Paid sources: such as Xianyu/Taobao.&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Synology NAS&lt;/p>
&lt;ul>
&lt;li>Synology&amp;rsquo;s official client, can access local network or external NAS resources. Here I use it to access some external NAS resources. If your NAS has WebDAV enabled, I still recommend using Infuse for a better experience; if not, this app works.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>Of course, besides these apps, the most recommended is &lt;code>AirPlay&lt;/code>. For example, if you find movie resources on your iPhone/iPad, you can directly AirPlay them to your TV to watch. This way, you no longer have to worry about not having resources or annoying video app ads.&lt;/p>
&lt;h3 id="settings">
&lt;a class="heading-anchor-link" href="#settings">Settings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="settings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Update the system to version 16+, enable Chinese Siri. Some apps like YouTube can use it.&lt;/li>
&lt;li>Log in with multiple accounts (Chinese mainland/ international). When downloading apps, just switch accounts.&lt;/li>
&lt;/ol>
&lt;h2 id="current-experience">
&lt;a class="heading-anchor-link" href="#current-experience">Current Experience&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-experience"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I&amp;rsquo;ve been using it for a few years now and have the following impressions:&lt;/p>
&lt;ol>
&lt;li>The TV/remote control experience is excellent. Xiaomi has only learned the superficial aspects and is far behind. Of course, Xiaomi&amp;rsquo;s products are cheaper.
&lt;ul>
&lt;li>Using your phone&amp;rsquo;s remote to enter long text is very convenient, or you can use your phone directly as a remote control.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>AirPlay is really great.&lt;/li>
&lt;/ol>
&lt;p>For Apple fans, I highly recommend buying it.&lt;/p>
&lt;h2 id="apple-tv-internet-access-issues">
&lt;a class="heading-anchor-link" href="#apple-tv-internet-access-issues">Apple TV Internet Access Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-tv-internet-access-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Apple TV has the ability to access the external internet, which is convenient for using resources. There are three main methods:&lt;/p>
&lt;ol>
&lt;li>Install a client on Apple TV.&lt;/li>
&lt;li>Solve it at the router level.&lt;/li>
&lt;li>Enable remote device connection on Mac/iPhone and change the network settings&amp;rsquo; gateway on Apple TV.&lt;/li>
&lt;/ol>
&lt;h2 id="how-to-check-your-apple-tv-model">
&lt;a class="heading-anchor-link" href="#how-to-check-your-apple-tv-model">How to Check Your Apple TV Model&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-to-check-your-apple-tv-model"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;a href="https://support.apple.com/en-us/101605" target="_blank" rel="noopener">https://support.apple.com/en-us/101605&lt;/a>&lt;/p></description></item><item><title>How to Use Vim (Step-by-Step Guide)</title><link>https://en.1991421.cn/2021/10/30/vim-usage/</link><pubDate>Sat, 30 Oct 2021 23:34:00 +0800</pubDate><guid>https://en.1991421.cn/2021/10/30/vim-usage/</guid><description>&lt;blockquote>
&lt;p>I was previously attracted by a colleague&amp;rsquo;s fast coding operation, and upon asking, I learned it was IdeaVim - &lt;code>a Vim plugin for IntelliJ IDEA&lt;/code>. I tried it for a while but felt uncomfortable with it, and there were also a lot of hotkey conflicts, so I gave up.&lt;/p>
&lt;p>Recently, I read a book &amp;ldquo;Practical Vim&amp;rdquo; and was attracted by Vim&amp;rsquo;s modal editing and the design philosophy behind all its commands. At the same time, a comment in the book moved me - &lt;code>one-time investment, lifelong benefit&lt;/code>.&lt;/p>
&lt;/blockquote>
&lt;p>I think it&amp;rsquo;s a bit embarrassing as a programmer to have never really used Vim, so I decided to learn it.&lt;/p>
&lt;img src="https://static.1991421.cn/2021/2021-10-30-235432.jpeg" style="zoom: 50%;" />
&lt;h2 id="vim-plugins">
&lt;a class="heading-anchor-link" href="#vim-plugins">Vim Plugins&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="vim-plugins"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>One of Vim&amp;rsquo;s strengths is its cross-platform compatibility and well-developed ecosystem. If you are familiar with the entire keyboard workflow, switching platforms will be smooth.&lt;/p>
&lt;p>Currently, after sorting, I have included two Vim plugins in my productivity tool system:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>IdeaVim&lt;/p>
&lt;p>Used in WebStorm IDE to improve coding efficiency.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Vimium&lt;/p>
&lt;p>Used in Chrome/Safari browsers for web scrolling, bookmark operations, etc., to improve efficiency.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="learning-cost">
&lt;a class="heading-anchor-link" href="#learning-cost">Learning Cost&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="learning-cost"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I didn&amp;rsquo;t stick with learning Vim before because of the learning cost. However, over the past few years, my persistent efforts in English translation, open-source project development, and self-developed productivity tools have brought me benefits that far exceed the initial costs.&lt;/p>
&lt;p>Now I have a new understanding of the so-called &amp;ldquo;learning cost&amp;rdquo;: cost is an investment. As long as the probability of high returns is high, then I should try it. So now I realize that it&amp;rsquo;s a pity I didn&amp;rsquo;t learn Vim earlier, and I&amp;rsquo;m no longer afraid, so I&amp;rsquo;m starting to learn it.&lt;/p>
&lt;h2 id="expectations---learning-benefits">
&lt;a class="heading-anchor-link" href="#expectations---learning-benefits">Expectations - Learning Benefits&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="expectations---learning-benefits"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>From now on, it will take a lot of time to master Vim proficiently, and I believe there will be two main gains:&lt;/p>
&lt;ol>
&lt;li>Vim&amp;rsquo;s functionality itself will further improve my efficiency, just like my previous set of hotkeys.&lt;/li>
&lt;li>Vim&amp;rsquo;s design philosophy will also bring me some reflections on software design.&lt;/li>
&lt;/ol></description></item><item><title>How uBlacklist Works</title><link>https://en.1991421.cn/2021/10/24/ublacklist/</link><pubDate>Sun, 24 Oct 2021 20:48:32 +0800</pubDate><guid>https://en.1991421.cn/2021/10/24/ublacklist/</guid><description>&lt;blockquote>
&lt;p>V2EX recently discussed the wave of content-farm results polluting Google (e.g., “Little X Knowledge”). Since we moved from Baidu to Google for better quality, seeing garbage in Google results is frustrating.&lt;/p>
&lt;p>The community solution: install uBlacklist, subscribe to a shared blacklist repo, and block those domains client-side. It works surprisingly well.&lt;/p>
&lt;/blockquote>
&lt;p>Curious about the implementation, I read the &lt;a href="https://github.com/iorate/uBlacklist/" target="_blank" rel="noopener">source code&lt;/a>. The core idea is simple: intercept the search results page, match entries against the blacklist, and hide them via CSS. In other words, the extension modifies the HTML after the page loads.&lt;/p>
&lt;p>Limitation: paginated results may show different counts per page because some entries get removed—but that’s acceptable compared with seeing spam.&lt;/p>
&lt;h2 id="what-about-baidu">
&lt;a class="heading-anchor-link" href="#what-about-baidu">What About Baidu?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-about-baidu"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>This approach requires result URLs to be present in the DOM. Baidu proxies all search results—links point to Baidu first—so uBlacklist can’t reliably match domains.&lt;/p>
&lt;p>In theory, you could fetch the proxied URL and inspect the redirect. But out of the box, uBlacklist currently supports Google, Bing, DuckDuckGo, Ecosia (partially), and Startpage.com.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Thanks to &lt;a href="https://github.com/iorate/uBlacklist" target="_blank" rel="noopener">https://github.com/iorate/uBlacklist&lt;/a> for cleaning up search results.&lt;/li>
&lt;li>It’d be nice if Google proactively filtered these sites.&lt;/li>
&lt;li>Baidu’s proxying of search results keeps traffic under its control. Yet another reason to avoid it.&lt;/li>
&lt;/ol></description></item><item><title>How to Use Wireshark (Step-by-Step Guide)</title><link>https://en.1991421.cn/2021/08/13/wireshark/</link><pubDate>Fri, 13 Aug 2021 21:53:47 +0800</pubDate><guid>https://en.1991421.cn/2021/08/13/wireshark/</guid><description>&lt;blockquote>
&lt;p>For web debugging, Chrome DevTools Network is often enough. For HTTPS MITM or iPhone captures on macOS, I use Surge. But if you want raw HTTP request/response bytes and to inspect layers beneath the application layer, Wireshark is the right tool.&lt;/p>
&lt;/blockquote>
&lt;p>I recently analyzed a download issue and found Wireshark powerful. Online docs are scattered, so here’s a consolidated summary.&lt;/p>
&lt;h2 id="what-is-wireshark">
&lt;a class="heading-anchor-link" href="#what-is-wireshark">What is Wireshark?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-is-wireshark"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>A network protocol analyzer.&lt;/p>
&lt;/blockquote>
&lt;p>As noted, Chrome shows application layer protocols (&lt;code>HTTP&lt;/code>, &lt;code>WebSocket&lt;/code>), while Surge focuses on &lt;code>HTTP&lt;/code>. For a full-stack view of protocols across layers, Wireshark shines.&lt;/p>
&lt;h2 id="common-issues">
&lt;a class="heading-anchor-link" href="#common-issues">Common Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="installation">
&lt;a class="heading-anchor-link" href="#installation">Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Select “Add Wireshark to the system path.pkg” so you can launch it from the command line.&lt;/p>
&lt;h3 id="the-capture-session-could-not-be-initiated-on-interface-en0-you-dont-have-permission-to-capture-on-that-device">
&lt;a class="heading-anchor-link" href="#the-capture-session-could-not-be-initiated-on-interface-en0-you-dont-have-permission-to-capture-on-that-device">The capture session could not be initiated on interface &amp;rsquo;en0&amp;rsquo; (You don&amp;rsquo;t have permission to capture on that device).&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-capture-session-could-not-be-initiated-on-interface-en0-you-dont-have-permission-to-capture-on-that-device"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-08-13-232934.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Fix:&lt;/p>
&lt;p>&lt;code>sudo chmod 777 /dev/bpf*&lt;/code>&lt;/p>
&lt;h3 id="capture-localhost">
&lt;a class="heading-anchor-link" href="#capture-localhost">Capture localhost&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="capture-localhost"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>To capture local traffic, double‑click &lt;code>loopback&lt;/code> on the start screen to begin capturing.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-08-13-234153.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="show-local-time">
&lt;a class="heading-anchor-link" href="#show-local-time">Show local time&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="show-local-time"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>By default, timestamps are “since capture started”. To show local time:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-08-13-234556.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="analysis-tips">
&lt;a class="heading-anchor-link" href="#analysis-tips">Analysis Tips&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="analysis-tips"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Highlight frames, then filter marked frames only: &lt;code>frame.marked == 1&lt;/code>&lt;/li>
&lt;li>Filter by source/destination IP: &lt;code>ip.src = 192.168.12.66 and ip.dst = 192.168.12.66&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="syncing-settings">
&lt;a class="heading-anchor-link" href="#syncing-settings">Syncing Settings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="syncing-settings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>It takes time to tune Wireshark (columns, coloring rules, plugins). To sync across devices and avoid losing configs, store them in iCloud (or similar) and symlink to Wireshark’s config directory.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">ln -s /Users/alanhe/Library/Mobile&lt;span class="se">\ &lt;/span>Documents/com~apple~CloudDocs/conf/wireshark /Users/alanhe/.config/wireshark
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I agree with this &lt;a href="https://www.zhihu.com/question/266935932/answer/316528916" target="_blank" rel="noopener">Zhihu answer&lt;/a>: in frontend work you may not often need Wireshark, but using it to understand the OSI model and full-stack protocols is a superpower.&lt;/p>
&lt;p>Learning in progress.&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.cnblogs.com/garfieldcgf/p/10006546.html" target="_blank" rel="noopener">https://www.cnblogs.com/garfieldcgf/p/10006546.html&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://zh.wikipedia.org/wiki/Wireshark" target="_blank" rel="noopener">https://zh.wikipedia.org/wiki/Wireshark&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.wireshark.org/docs//wsug_html_chunked/index.html" target="_blank" rel="noopener">https://www.wireshark.org/docs//wsug_html_chunked/index.html&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>What Is Dva? A Simple Guide</title><link>https://en.1991421.cn/2021/06/27/dva-intro/</link><pubDate>Sun, 27 Jun 2021 16:52:05 +0800</pubDate><guid>https://en.1991421.cn/2021/06/27/dva-intro/</guid><description>&lt;blockquote>
&lt;p>Some company projects use &lt;code>DvaJS (D.va)&lt;/code>. To use it better, I researched and summarized notes here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="overview">
&lt;a class="heading-anchor-link" href="#overview">Overview&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="overview"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>React and redux based, lightweight and elm-style framework.&lt;/p>
&lt;p>First and foremost, dva is a data flow solution based on redux and redux-saga. To simplify the development experience, dva also includes built-in react-router and fetch, so it can be understood as a lightweight application framework.&lt;/p>
&lt;p>dva does three main things:&lt;/p>
&lt;ul>
&lt;li>Unifies store and saga into a single &amp;ldquo;model&amp;rdquo; concept, written in one JavaScript file&lt;/li>
&lt;li>Adds Subscriptions to collect actions from other sources, such as keyboard operations&lt;/li>
&lt;li>Model syntax is very concise, similar to DSL or RoR, making coding very fast ✈️&lt;/li>
&lt;/ul>
&lt;/blockquote>
&lt;p>So dva focuses on Redux‑based data flow, with built‑in react‑router and fetch.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-07-18-140937.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-07-18-153006.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="usage">
&lt;a class="heading-anchor-link" href="#usage">Usage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="dvajs">
&lt;a class="heading-anchor-link" href="#dvajs">dva.js&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="dvajs"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// products-model.js
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">export&lt;/span> &lt;span class="k">default&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Key on global state
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">namespace&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;products&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Initial value, here is an empty array
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">state&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Equivalent to reducer in redux, receives action, updates state synchronously
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">reducers&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;delete&amp;#39;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">state&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">payload&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">id&lt;/span> &lt;span class="p">})&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">state&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">filter&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">item&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="nx">item&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">id&lt;/span> &lt;span class="o">!==&lt;/span> &lt;span class="nx">id&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">subscriptions&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Initialize dva application
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">const&lt;/span> &lt;span class="nx">app&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">dva&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">initialState&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">products&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;dva&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">id&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;antd&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">id&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Register view
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">model&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">productsModel&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="k">default&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">router&lt;/span>&lt;span class="p">(()&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="nx">ConnectedApp&lt;/span> &lt;span class="o">/&amp;gt;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Start the application
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">start&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;#root&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="model-reuse">Model reuse&lt;/h4>&lt;p>dva-model-extend&lt;/p>
&lt;blockquote>
&lt;p>Utility method to extend dva model.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;a href="https://github.com/dvajs/dva-model-extend" target="_blank" rel="noopener">https://github.com/dvajs/dva-model-extend&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">modelExtend&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;dva-model-extend&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">human&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">state&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">stomach&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">reducers&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">eat&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">state&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">payload&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">food&lt;/span> &lt;span class="p">})&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="p">...&lt;/span>&lt;span class="nx">state&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">stomach&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">food&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">benjy&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">modelExtend&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">human&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">namespace&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;human.benjy&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">state&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Benjy&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="source">
&lt;a class="heading-anchor-link" href="#source">Source&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="source"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>The project uses &lt;a href="https://github.com/lerna/lerna" target="_blank" rel="noopener">lerna&lt;/a> for multi-package management&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-mysql" data-lang="mysql">&lt;span class="line">&lt;span class="cl">&lt;span class="err">├──&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dva&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Official&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">React&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">bindings&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dva&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">with&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">react&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">router&lt;/span>&lt;span class="o">@&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="err">├──&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dva&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">core&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">The&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">core&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">lightweight&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">library&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dva&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">based&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">on&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">redux&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">and&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">redux&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">saga&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="err">├──&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dva&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">immer&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">Create&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">the&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">next&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">immutable&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">state&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">tree&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">by&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">simply&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">modifying&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">the&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">current&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">tree&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="err">└──&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dva&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">loading&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Auto&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">loading&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">binding&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">plugin&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dva&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="n">clap&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">You&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">don&lt;/span>&lt;span class="s1">&amp;#39;t need to write `showLoading` and `hideLoading` any more.
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="code-size">
&lt;a class="heading-anchor-link" href="#code-size">Code size&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="code-size"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;blockquote>
&lt;p>JavaScript source code in /packages, statistics script &lt;code>cloc . --md --exclude-dir=test --include-ext=js&lt;/code>&lt;/p>
&lt;/blockquote>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align: left">Language&lt;/th>
&lt;th style="text-align: right">files&lt;/th>
&lt;th style="text-align: right">blank&lt;/th>
&lt;th style="text-align: right">comment&lt;/th>
&lt;th style="text-align: right">code &lt;code>physical lines&lt;/code>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align: left">JavaScript&lt;/td>
&lt;td style="text-align: right">26&lt;/td>
&lt;td style="text-align: right">128&lt;/td>
&lt;td style="text-align: right">110&lt;/td>
&lt;td style="text-align: right">&lt;span style="background-color:yellow;">962&lt;/span>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: left">&amp;mdash;&amp;mdash;&amp;ndash;&lt;/td>
&lt;td style="text-align: right">&amp;mdash;&amp;mdash;&amp;ndash;&lt;/td>
&lt;td style="text-align: right">&amp;mdash;&amp;mdash;&amp;ndash;&lt;/td>
&lt;td style="text-align: right">&amp;mdash;&amp;mdash;&amp;ndash;&lt;/td>
&lt;td style="text-align: right">&amp;mdash;&amp;mdash;&amp;ndash;&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: left">SUM:&lt;/td>
&lt;td style="text-align: right">26&lt;/td>
&lt;td style="text-align: right">128&lt;/td>
&lt;td style="text-align: right">110&lt;/td>
&lt;td style="text-align: right">962&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;ul>
&lt;li>&lt;a href="https://webpack.js.org/guides/tree-shaking/" target="_blank" rel="noopener">sideEffects : false&lt;/a>&lt;/li>
&lt;li>Uses ES syntax, and exports in CommonJS format for third-party tools&lt;/li>
&lt;/ul>
&lt;p>The small code size suggests a lightweight abstraction.&lt;/p>
&lt;h3 id="key-functions">
&lt;a class="heading-anchor-link" href="#key-functions">Key functions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="key-functions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;h4 id="dva">dva()&lt;/h4>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// packages/dva/src/index.js
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">export&lt;/span> &lt;span class="k">default&lt;/span> &lt;span class="kd">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">opts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{})&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">history&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">history&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="nx">createHashHistory&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">createOpts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">initialReducer&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">router&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">connectRouter&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">history&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">setupMiddlewares&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">middlewares&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="nx">routerMiddleware&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">history&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="p">...&lt;/span>&lt;span class="nx">middlewares&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">setupApp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">app&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_history&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">patchHistory&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">history&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">app&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">create&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">opts&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">createOpts&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">//
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kr">const&lt;/span> &lt;span class="nx">oldAppStart&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">start&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">router&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">router&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">start&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">start&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="model">model()&lt;/h4>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// packages/dva-core/src/index.js
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kd">function&lt;/span> &lt;span class="nx">injectModel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">createReducer&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">onError&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">unlisteners&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">m&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">model&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">store&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_store&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">store&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">asyncReducers&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">namespace&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">getReducer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">reducers&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">state&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">plugin&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_handleActions&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">store&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replaceReducer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">createReducer&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">effects&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">store&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">runSaga&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_getSaga&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">effects&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">onError&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">plugin&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;onEffect&amp;#39;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="nx">hooksAndOpts&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">subscriptions&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">unlisteners&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">namespace&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">runSubscription&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">subscriptions&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">onError&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="subscriptions">subscriptions&lt;/h4>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// packages/dva-core/src/subscription.js
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">export&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="nx">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">subs&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">model&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">onError&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">funcs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">nonFuncs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Loop through and execute each subscription function
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kr">const&lt;/span> &lt;span class="nx">key&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">subs&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">Object&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">prototype&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">hasOwnProperty&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">call&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">subs&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">key&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">sub&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">subs&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">unlistener&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">sub&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">dispatch&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">prefixedDispatch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_store&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dispatch&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">model&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">history&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_history&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">onError&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">isFunction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">unlistener&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">funcs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">unlistener&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">nonFuncs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">funcs&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">nonFuncs&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="start">start()&lt;/h4>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// packages/dva/src/index.js
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kd">function&lt;/span> &lt;span class="nx">start&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">container&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Allow container to be a string, then use querySelector to find the element
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">isString&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">container&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">container&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">document&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">querySelector&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">container&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">invariant&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">container&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="sb">`[app.start] container &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">container&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb"> not found`&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Validate container type
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">invariant&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">!&lt;/span>&lt;span class="nx">container&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="nx">isHTMLElement&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">container&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="sb">`[app.start] container should be HTMLElement`&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Check if router is registered
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">invariant&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_router&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="sb">`[app.start] router must be registered before app.start()`&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">//
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_store&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">oldAppStart&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">call&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">app&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">store&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_store&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// export _getProvider for HMR
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ref: https://github.com/dvajs/dva/issues/469
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_getProvider&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">getProvider&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">bind&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">store&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// If has container, render; else, return react component
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">container&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">render&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">container&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">store&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_router&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Handle hot module replacement
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_plugin&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">apply&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;onHmr&amp;#39;&lt;/span>&lt;span class="p">)(&lt;/span>&lt;span class="nx">render&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">bind&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">container&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">store&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">app&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">getProvider&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">store&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_router&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="pluginuse">plugin/use()&lt;/h4>&lt;p>In dva, classes are used in only two places: dynamic component loading and plugin definitions&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">use&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">plugin&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">invariant&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isPlainObject&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">plugin&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="s1">&amp;#39;plugin.use: plugin should be plain object&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">hooks&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kr">const&lt;/span> &lt;span class="nx">key&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">plugin&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">Object&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">prototype&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">hasOwnProperty&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">call&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">plugin&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">key&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">invariant&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">hooks&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="sb">`plugin.use: unknown plugin property: &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">key&lt;/span> &lt;span class="o">===&lt;/span> &lt;span class="s1">&amp;#39;_handleActions&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_handleActions&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">plugin&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">key&lt;/span> &lt;span class="o">===&lt;/span> &lt;span class="s1">&amp;#39;extraEnhancers&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">hooks&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">plugin&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">hooks&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">plugin&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">]);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Reading the source code shows that dva&amp;rsquo;s encapsulation is relatively shallow, but it solves the logic organization problem around redux, while providing routing configuration/subscriptions and plugin extensions.&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://github.com/dvajs/dva/issues/1" target="_blank" rel="noopener">Introduction to dva&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/venaissance/myBlog/issues/20" target="_blank" rel="noopener">Thoroughly Understanding DvaJS Principles&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/sorrycc/blog/issues/1" target="_blank" rel="noopener">React + Redux Best Practices&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Custom Calendar Publishing and Subscription</title><link>https://en.1991421.cn/2021/04/22/custom-calendar-publish/</link><pubDate>Thu, 22 Apr 2021 20:08:09 +0800</pubDate><guid>https://en.1991421.cn/2021/04/22/custom-calendar-publish/</guid><description>&lt;blockquote>
&lt;p>Fantastical or TickTick support calendar subscriptions. Generally, we look for quality calendar sources, such as legal holidays and work adjustments. After knowing the corresponding calendar, we also need to pay attention to whether the author continues to maintain it, otherwise there will be time-sensitive issues.&lt;/p>
&lt;p>So can we maintain a calendar ourselves? The answer is YES. Here I&amp;rsquo;ll use the most basic &lt;code>China Holiday Arrangements&lt;/code> to introduce how to maintain a calendar yourself.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-04-22-202027.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="information-reference-source">
&lt;a class="heading-anchor-link" href="#information-reference-source">Information Reference Source&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="information-reference-source"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Since I want to create a holiday calendar, I need to refer to the State Council&amp;rsquo;s arrangements. Information source - &lt;a href="http://www.gov.cn/zhengce/content/2020-11/25/content_5564127.htm" target="_blank" rel="noopener">Notice of the General Office of the State Council on Some Holiday Arrangements for 2021&lt;/a>&lt;/p>
&lt;p>Note: Since each year will be different, if it&amp;rsquo;s a new year, I still need to maintain it manually, but the workload is very small, just a few minutes of work.&lt;/p>
&lt;h2 id="calendar-creation">
&lt;a class="heading-anchor-link" href="#calendar-creation">Calendar Creation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="calendar-creation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For those curious about how to make it, continue reading. Here I use Calendar on iCloud to create it. The advantage is that it can be directly hosted and published, and others can directly add and use the calendar.&lt;/p>
&lt;ol>
&lt;li>Visit &lt;a href="https://www.icloud.com.cn/calendar/" target="_blank" rel="noopener">https://www.icloud.com.cn/calendar/&lt;/a>
&lt;ul>
&lt;li>For overseas regions, please visit &lt;a href="https://www.icloud.com/calendar/" target="_blank" rel="noopener">https://www.icloud.com/calendar/&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Click to create a new calendar&lt;/li>
&lt;li>Edit events&lt;/li>
&lt;li>Select calendar, click the share button&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-04-22-201427.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="usage">
&lt;a class="heading-anchor-link" href="#usage">Usage&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>There are multiple ways to use this&lt;/p>
&lt;ul>
&lt;li>Visit the subscription address directly in the browser, follow the prompts, and select the appropriate app like Outlook to open&lt;/li>
&lt;li>Use apps like &lt;code>Fantastical&lt;/code> directly for calendar subscription&lt;/li>
&lt;/ul>
&lt;h2 id="share-my-calendar-subscription">
&lt;a class="heading-anchor-link" href="#share-my-calendar-subscription">Share My Calendar Subscription&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="share-my-calendar-subscription"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Click &lt;a href="https://www.shuyz.com/githubfiles/china-holiday-calender/master/holidayCal.ics" target="_blank" rel="noopener">Download&lt;/a>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-26-175344.jpeg"
alt="https://static.1991421.cn/2025/2025-05-26-175344.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-words">
&lt;a class="heading-anchor-link" href="#final-words">Final Words&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-words"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I used to be quite curious about how calendar events are edited and published. After doing it once, I found it&amp;rsquo;s quite simple. To extend this, using the calendar event system, for example, some key release plans at work can be done this way, so everyone can quickly understand the product&amp;rsquo;s release plan. Another example is following TV series - you can update Marvel&amp;rsquo;s release schedule for several years, which is also a good approach.&lt;/p>
&lt;h2 id="related-documents">
&lt;a class="heading-anchor-link" href="#related-documents">Related Documents&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-documents"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.gov.cn/zhengce/content/202310/content_6911527.htm" target="_blank" rel="noopener">Notice of the General Office of the State Council on Some Holiday Arrangements for 2024&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Chained Assignment in JavaScript</title><link>https://en.1991421.cn/2021/03/25/js-chained-assignment/</link><pubDate>Thu, 25 Mar 2021 23:11:53 +0800</pubDate><guid>https://en.1991421.cn/2021/03/25/js-chained-assignment/</guid><description>&lt;blockquote>
&lt;p>I ran into a seemingly easy JavaScript puzzle in a chat group today and still got it wrong, so I’m jotting it down.&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">user&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">user&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">user&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">user&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">x&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="wrong-turn-1">
&lt;a class="heading-anchor-link" href="#wrong-turn-1">&lt;del>Wrong Turn #1&lt;/del>&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wrong-turn-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I assumed it was equivalent to the code below:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">user&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">user&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">user&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">user&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">user&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">x&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * {n: 2, x: {…}}
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> */&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Running it in the browser or Node showed the actual answer is &lt;code>undefined&lt;/code>.&lt;/p>
&lt;h2 id="wrong-turn-2">
&lt;a class="heading-anchor-link" href="#wrong-turn-2">&lt;del>Wrong Turn #2&lt;/del>&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wrong-turn-2"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I went back to review the assignment operator. For chained assignment specifically:&lt;/p>
&lt;blockquote>
&lt;p>Chaining the assignment operator is possible in order to assign a single value to multiple variables.&lt;/p>
&lt;/blockquote>
&lt;p>So &lt;code>a = b = c&lt;/code> should behave like &lt;code>b = c; a = c;&lt;/code>.&lt;/p>
&lt;p>By that logic, I rewrote the snippet as:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">user&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">user&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">user&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">user&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">x&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>I figured that must be correct, but the browser printed &lt;code>{n: 2}&lt;/code>—still wrong. The missing piece? The member-access operator.&lt;/p>
&lt;h2 id="the-real-answer">
&lt;a class="heading-anchor-link" href="#the-real-answer">The Real Answer&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-real-answer"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>The dot operator for member access has higher precedence than assignment.&lt;/p>
&lt;/blockquote>
&lt;p>Let’s analyze it again:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">user&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">user&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">user&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">user&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">x&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * user.x points to the original object (call it “1”).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * The object literal {n: 2} is assigned to that original object&amp;#39;s x.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * The final assignment rebinds user to a new object (call it “2”).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * console.log reads x from “2”, which has no such property, so the result is undefined.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> */&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A simple question, yet it tripped me up—reminder that fundamentals matter. A few key takeaways:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>The dot operator has higher precedence than assignment.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Chained assignment copies a single value into multiple variables, and it evaluates from right to left. You can prove this with a quick Proxy experiment:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">superman&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;clark&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">batman&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">flashman&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">batmanProxy&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nb">Proxy&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">batman&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">set&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">target&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">key&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sb">`batman: &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb"> set from &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">target&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb"> to &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">target&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">flashmanProxy&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nb">Proxy&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">flashman&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">set&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">target&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">key&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sb">`flashman: &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb"> set from &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">target&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb"> to &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">target&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">get&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">target&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">key&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sb">`flashman: &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb"> get from &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">target&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">target&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">key&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">batmanProxy&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">flashmanProxy&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">superman&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">name&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The logs show &lt;code>flashman&lt;/code>’s setter firing first. Also note this is not the same as &lt;code>batmanProxy.name = (flashmanProxy.name = superman.name);&lt;/code> because the proxy’s getter never runs.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Object assignment copies references, not values.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Elementary question, valuable lesson. Back to studying—and back to slinging code.&lt;/p></description></item><item><title>Clever Uses of Zero-Width Characters</title><link>https://en.1991421.cn/2021/03/08/zero-width-characters/</link><pubDate>Mon, 08 Mar 2021 14:10:19 +0800</pubDate><guid>https://en.1991421.cn/2021/03/08/zero-width-characters/</guid><description>&lt;blockquote>
&lt;p>I recently learned about zero-width characters and found them quite interesting, so I&amp;rsquo;m documenting this here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-03-08-142958.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Above is an &amp;ldquo;empty&amp;rdquo; Weibo post I sent using zero-width spaces, and it worked! However, the same method doesn&amp;rsquo;t work on WeChat Moments or Twitter, likely because their empty content detection logic filters out zero-width characters.&lt;/p>
&lt;p>OK, let&amp;rsquo;s begin the main content.&lt;/p>
&lt;h2 id="zero-width-characters">
&lt;a class="heading-anchor-link" href="#zero-width-characters">Zero-Width Characters&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="zero-width-characters"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Unicode includes a special class of characters called zero-width characters. The term &amp;ldquo;zero-width&amp;rdquo; should be familiar - regex assertions are called zero-width assertions, meaning they don&amp;rsquo;t consume width, which makes them easy to understand.&lt;/p>
&lt;p>Zero-width characters are still characters and thus occupy character space, but they typically don&amp;rsquo;t display in most software like Sina Weibo, browsers, Excel, WeChat, etc.&lt;/p>
&lt;p>There are several types of zero-width characters: zero-width space, zero-width joiner, and zero-width non-joiner.&lt;/p>
&lt;ul>
&lt;li>Zero-width space &lt;code>U+200B&lt;/code>&lt;/li>
&lt;li>Zero-width joiner &lt;code>U+200D&lt;/code>
&lt;ul>
&lt;li>Common complex emoji expressions use this character to indicate multi-character relationships for composing complex new characters&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Zero-width non-joiner &lt;code>U+200C&lt;/code>&lt;/li>
&lt;li>Zero-width no-break space &lt;code>U+FEFF&lt;/code>&lt;/li>
&lt;li>Left-to-right mark &lt;code>U+200E&lt;/code>&lt;/li>
&lt;li>Right-to-left mark &lt;code>U+200F&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="clever-uses">
&lt;a class="heading-anchor-link" href="#clever-uses">Clever Uses&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="clever-uses"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Watermarking&lt;/p>
&lt;ul>
&lt;li>
&lt;p>For websites with strict copyright requirements, convert article visitor usernames to zero-width characters and hide them within article content. This doesn&amp;rsquo;t affect readability while marking user information. If article content leaks, simply decode the username to identify the leak source.&lt;/p>
&lt;p>As shown below, the left side shows what we see, but I actually encoded my name into the information. The right side shows the decoded name.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-03-08-145705.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Evading Keyword Matching&lt;/p>
&lt;ul>
&lt;li>Insert zero-width characters within keywords to evade some keyword matching programs&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="invisibility">
&lt;a class="heading-anchor-link" href="#invisibility">Invisibility&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="invisibility"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As mentioned above, these characters are invisible in most software. To see them, you can use development tools like VSC or IDEA to create text files and paste content to reveal these hidden characters.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-03-08-145154.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="recommended-tools">
&lt;a class="heading-anchor-link" href="#recommended-tools">Recommended Tools&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="recommended-tools"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you want to implement zero-width character watermarking for text, you can refer to these tools:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/yuanfux/zero-width-lib" target="_blank" rel="noopener">https://github.com/yuanfux/zero-width-lib&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/umpox/zero-width-detection" target="_blank" rel="noopener">https://github.com/umpox/zero-width-detection&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>A Visit to the 306 Hospital</title><link>https://en.1991421.cn/2021/02/19/hospital-visit-306/</link><pubDate>Fri, 19 Feb 2021 22:12:37 +0800</pubDate><guid>https://en.1991421.cn/2021/02/19/hospital-visit-306/</guid><description>&lt;h2 id="what-to-bring">
&lt;a class="heading-anchor-link" href="#what-to-bring">What to Bring&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-to-bring"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Medical Insurance Card&lt;/strong>: For reimbursement of partial costs.&lt;/li>
&lt;li>&lt;strong>Smartphone&lt;/strong>: For retrieving registration numbers and paying for medication.&lt;/li>
&lt;li>&lt;strong>ID Card&lt;/strong>: In case of unexpected requirements.&lt;/li>
&lt;/ul>
&lt;h2 id="step-by-step-process">
&lt;a class="heading-anchor-link" href="#step-by-step-process">Step-by-Step Process&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="step-by-step-process"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>&lt;strong>Appointment&lt;/strong>: Use the official WeChat account &lt;code>PLA Strategic Support Force Specialty Medical Center&lt;/code> for online appointments. &lt;em>Note: You must book at least one day in advance; same-day appointments are not allowed.&lt;/em> Alternatively, use &lt;a href="https://www.114yygh.com/" target="_blank" rel="noopener">114 Registration&lt;/a>.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Recommendation&lt;/strong>: I found &lt;code>114 Registration&lt;/code> to provide a much better user experience with clearer information on available slots. Scan the QR code below via WeChat to access it:&lt;/p>
&lt;img alt="Hospital Visit 306 - 114 Registration QR" src="https://img.114yygh.com/staticres/web/code_home.png" style="zoom: 50%;" />
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Pre-screening&lt;/strong>: Fill out the pre-screening form (formerly for COVID-19). Note: This is no longer required as of late.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Check-in&lt;/strong>: Go to the outpatient building and use the self-service machines to retrieve your registration number.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Queueing&lt;/strong>: Proceed to the designated waiting area as indicated on your ticket and check in with the nurse station.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Consultation&lt;/strong>: Wait for your number to be called and enter the consultation room.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Payment&lt;/strong>: Take the prescription/order from the doctor and pay at the self-service machines in the outpatient building. &lt;em>Note: Traditional Chinese Medicine (TCM) orders may require manual queueing at a counter.&lt;/em>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Pharmacy&lt;/strong>: Pick up your medication at the pharmacy counter as per your payment receipt.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Invoices&lt;/strong>: If you need to file a claim with commercial insurance, visit the designated window in the outpatient building to get a printed invoice (including the registration fee).&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="critical-observations">
&lt;a class="heading-anchor-link" href="#critical-observations">Critical Observations&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="critical-observations"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Official Website Performance&lt;/strong>: The official appointment site is incredibly slow. Users might easily mistake it for a dead link or a device issue. Stick to 114 instead.&lt;/li>
&lt;li>&lt;strong>Lack of Clear Communication&lt;/strong>: There&amp;rsquo;s confusing messaging about onsite vs. online appointments. I waited 30 minutes in a queue marked &amp;ldquo;Registration&amp;rdquo; only to be told I had to book online. Hospitals should provide clear, large signage for these policies.&lt;/li>
&lt;li>&lt;strong>Inefficient Payment Systems&lt;/strong>: The 30+ minute queue for payment is inexcusable in the digital age. This is particularly difficult for elderly patients who may struggle with technology or have hearing issues.&lt;/li>
&lt;li>&lt;strong>Counter Allocation&lt;/strong>: As a military hospital, prioritizing personnel is expected. However, when the &amp;ldquo;General&amp;rdquo; counter has a massive queue and the two &amp;ldquo;Military&amp;rdquo; counters are empty, management should dynamically reassign staff to alleviate the pressure.&lt;/li>
&lt;li>&lt;strong>Flow Management&lt;/strong>: Many people in queues are simply there to ask questions because they lack information. Increasing the number of mobile medical staff to assist patients in the halls would significantly improve overall efficiency.&lt;/li>
&lt;li>&lt;strong>Doctor Conduct&lt;/strong>: While I understand doctors are overworked, a heavy workload is no excuse for a hostile or dismissive attitude toward paying patients.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The management needs a serious reality check. The leaders should go through the entire process as an ordinary patient to understand where the system is failing.&lt;/p></description></item><item><title>Managing Compatibility with Browserslist</title><link>https://en.1991421.cn/2021/02/02/browserslist/</link><pubDate>Tue, 02 Feb 2021 17:39:29 +0800</pubDate><guid>https://en.1991421.cn/2021/02/02/browserslist/</guid><description>&lt;blockquote>
&lt;p>The web pages we develop need to run on various browsers, and different browsers and versions all have slight differences in page parsing. If it&amp;rsquo;s IE, it&amp;rsquo;s even more troublesome. At one time, frontend developers would groan when talking about IE compatibility, cursing IE countless times in their hearts.&lt;/p>
&lt;p>How to elegantly handle compatibility issues is a constant challenge. Now there are relatively systematic solutions to this problem, which I&amp;rsquo;ll document here.&lt;/p>
&lt;/blockquote>
&lt;p>Note: Different scenarios and habits lead to different configuration methods. Here I&amp;rsquo;ll explain based on my personal practice, for reference only.&lt;/p>
&lt;h2 id="browserslist">
&lt;a class="heading-anchor-link" href="#browserslist">Browserslist&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="browserslist"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="configuration">
&lt;a class="heading-anchor-link" href="#configuration">Configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="configuration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Create a &lt;code>.browserslistrc&lt;/code> file in the project root directory and write down the target browser range according to your requirements. For example, my configuration is as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl"># Browsers that we support
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">last 1 years
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Meaning: Support browsers and versions from the last year.&lt;/p>
&lt;p>For specific Browserslist configuration syntax, &lt;a href="https://github.com/browserslist/browserslist#query-composition" target="_blank" rel="noopener">click here&lt;/a>&lt;/p>
&lt;h3 id="testing">
&lt;a class="heading-anchor-link" href="#testing">Testing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="testing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>After configuration, execute the following command in the terminal to get the list of target browser versions:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">$ npx browserslist
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-02-03-094437.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="note">
&lt;a class="heading-anchor-link" href="#note">Note&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="note"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>
&lt;p>Browserslist only provides a mechanism to conveniently set and retrieve target browsers and their versions&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Actual compatibility handling still requires other tools to detect and fix based on the browser list&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Below, continue with installation and configuration.&lt;/p>
&lt;h2 id="eslint-plugin-compat">
&lt;a class="heading-anchor-link" href="#eslint-plugin-compat">eslint-plugin-compat&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="eslint-plugin-compat"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="installation">
&lt;a class="heading-anchor-link" href="#installation">Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ yarn add eslint-plugin-compat -D
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="configuration-1">
&lt;a class="heading-anchor-link" href="#configuration-1">Configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="configuration-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Add the following configuration to &lt;code>.eslintrc.js&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">module&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">exports&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">root&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">extends&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;plugin:compat/recommended&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">rules&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;compat/compat&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;error&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Run &lt;code>eslint src/main/webapp/**/*.{ts,tsx} --quiet&lt;/code> to perform compatibility detection based on target browsers. If there are errors, they will be displayed.&lt;/p>
&lt;p>Since my browser support above is quite modern, compatibility issues aren&amp;rsquo;t likely to appear. For example, if I change my browser list to &lt;code>last 10 years&lt;/code>, then errors will appear:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-02-03-095540.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="note-1">
&lt;a class="heading-anchor-link" href="#note-1">Note&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="note-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;code>eslint-plugin-compat&lt;/code> mainly focuses on WEB API and doesn&amp;rsquo;t check ES API. Therefore, other Lint plugins are needed to detect ES API compatibility.&lt;/p>
&lt;h2 id="eslint-plugin-es">
&lt;a class="heading-anchor-link" href="#eslint-plugin-es">eslint-plugin-es&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="eslint-plugin-es"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>This plugin is designed for ES detection. For example, lookbehind assertions in ES9 are not supported by Safari, so we need to add corresponding rules to block this usage.&lt;/p>
&lt;/blockquote>
&lt;h3 id="installation-1">
&lt;a class="heading-anchor-link" href="#installation-1">Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installation-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>For example, to block lookbehind assertions, the following configuration is needed:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ yarn add es/no-regexp-lookbehind-assertions -D
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="configuration-2">
&lt;a class="heading-anchor-link" href="#configuration-2">Configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="configuration-2"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Add the following rule to &lt;code>.eslintrc.js&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;es/no-regexp-lookbehind-assertions&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;error&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="css">
&lt;a class="heading-anchor-link" href="#css">CSS&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="css"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>CSS issues are similar to JS, but CSS itself won&amp;rsquo;t cause page white screens, only some styles that don&amp;rsquo;t work. At the same time, postcss can generate specified CSS syntax for target browsers.&lt;/p>
&lt;h3 id="installation-2">
&lt;a class="heading-anchor-link" href="#installation-2">Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installation-2"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ yarn add postcss-loader -D
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ yarn add stylelint-no-unsupported-browser-features -D
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ yarn add obsolete-webpack-plugin -D
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="configuration-3">
&lt;a class="heading-anchor-link" href="#configuration-3">Configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="configuration-3"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Add the following configuration to &lt;code>.stylelintrc.json&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;plugins&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;stylelint-no-unsupported-browser-features&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;rules&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;plugin/no-unsupported-browser-features&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;severity&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;warning&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Add configuration to Webpack:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">test&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="sr">/\.css$/&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">use&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;postcss-loader&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol>
&lt;li>When executing the stylelint command &lt;code>stylelint src/main/webapp/**/*.less --syntax=less&lt;/code>, it can detect style support in target browsers&lt;/li>
&lt;li>postcss automatically adds some compatible style syntax to ensure styles work in target browsers&lt;/li>
&lt;/ol>
&lt;h2 id="obsolete-webpack-plugin">
&lt;a class="heading-anchor-link" href="#obsolete-webpack-plugin">obsolete-webpack-plugin&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="obsolete-webpack-plugin"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When a page is not supported, it sometimes shows a blank screen, which is a terrible user experience. Therefore, detection scripts can be added to alert users, and this plugin solves this problem.&lt;/p>
&lt;h3 id="installation-3">
&lt;a class="heading-anchor-link" href="#installation-3">Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="installation-3"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ yarn add obsolete-webpack-plugin -D
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="configuration-4">
&lt;a class="heading-anchor-link" href="#configuration-4">Configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="configuration-4"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">plugins&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="k">new&lt;/span> &lt;span class="nx">ObsoleteWebpackPlugin&lt;/span>&lt;span class="p">()]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="testing-1">
&lt;a class="heading-anchor-link" href="#testing-1">Testing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="testing-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After packaging, an obsolete.js script file will be generated, and index.html will include this JS.&lt;/p>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>As shown above, we can effectively manage frontend browser compatibility.&lt;/li>
&lt;li>If the target browser and version range changes, all you need to do is &lt;code>modify browserslist =&amp;gt; detect JS, CSS =&amp;gt; fix according to error prompts&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://watofundefined.dev/posts/regexp-lookbehinds-bit-me-in-the-behind/" target="_blank" rel="noopener">https://watofundefined.dev/posts/regexp-lookbehinds-bit-me-in-the-behind/&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Nintendo Switch Game Purchase Strategy</title><link>https://en.1991421.cn/2021/01/22/nintendo/</link><pubDate>Fri, 22 Jan 2021 23:27:17 +0800</pubDate><guid>https://en.1991421.cn/2021/01/22/nintendo/</guid><description>&lt;blockquote>
&lt;p>Here I summarize my personal NS game purchase strategy.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-22-235007.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Since NS game prices vary across regions, using multiple accounts can save some RMB while keeping games playable.&lt;/p>
&lt;p>How to do it? Here&amp;rsquo;s the approach:&lt;/p>
&lt;h2 id="gmail-multiple-email-aliases">
&lt;a class="heading-anchor-link" href="#gmail-multiple-email-aliases">Gmail multiple email aliases&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="gmail-multiple-email-aliases"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Recommended alias strategy for multi-region account management. For example, if my email is &lt;a href="mailto:alanhe@gmail.com">alanhe@gmail.com&lt;/a>, I create aliases like:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="mailto:alanhe&amp;#43;us@gmail.com">alanhe+us@gmail.com&lt;/a> for US&lt;/li>
&lt;li>&lt;a href="mailto:alanhe&amp;#43;jp@gmail.com">alanhe+jp@gmail.com&lt;/a> for Japan&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-22-233253.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="nintendo-account-registration">
&lt;a class="heading-anchor-link" href="#nintendo-account-registration">Nintendo account registration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="nintendo-account-registration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Use &lt;a href="https://accounts.nintendo.com/login" target="_blank" rel="noopener">https://accounts.nintendo.com/login&lt;/a> to create new accounts. Nicknames can be like:&lt;/p>
&lt;ul>
&lt;li>AlanHeUS&lt;/li>
&lt;li>AlanHeJP&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-22-233837.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Use consistent passwords&lt;/li>
&lt;li>Ensure country/region matches the account name and email&lt;/li>
&lt;/ul>
&lt;h2 id="add-accounts-on-nintendo-switch">
&lt;a class="heading-anchor-link" href="#add-accounts-on-nintendo-switch">Add accounts on Nintendo Switch&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="add-accounts-on-nintendo-switch"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Entering passwords with controllers is inconvenient, so use the touchscreen. The display name can differ from the account nickname, but I recommend using the same pattern for easier management. Bind the account to the Nintendo account created above and you&amp;rsquo;re done.&lt;/p>
&lt;h2 id="check-target-game-prices">
&lt;a class="heading-anchor-link" href="#check-target-game-prices">Check target game prices&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="check-target-game-prices"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I recommend the WeChat mini program &lt;code>Master in Hand&lt;/code> to check prices across countries.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-22-234151.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="purchase-on-eshop">
&lt;a class="heading-anchor-link" href="#purchase-on-eshop">Purchase on eShop&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchase-on-eshop"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Log in to the target region&amp;rsquo;s eShop account and buy the game.&lt;/p>
&lt;h3 id="notes-1">
&lt;a class="heading-anchor-link" href="#notes-1">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Payment methods are usually &lt;code>PayPal&lt;/code> or &lt;code>Visa&lt;/code>.&lt;/li>
&lt;li>Brazil requires a tax ID, and mainland China Visa cards do not work.&lt;/li>
&lt;li>If using PayPal, you need a proxy. You can connect the NS to your phone and use the phone&amp;rsquo;s proxy, or connect the NS to a home router with proxy support.&lt;/li>
&lt;/ul>
&lt;h2 id="games-ive-purchased">
&lt;a class="heading-anchor-link" href="#games-ive-purchased">Games I&amp;rsquo;ve purchased&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="games-ive-purchased"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here are the games I own/like:&lt;/p>
&lt;ol>
&lt;li>Ring Fit Adventure
&lt;ul>
&lt;li>Cartridge&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Mario Kart 8
&lt;ul>
&lt;li>Cartridge&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Just Dance 2021
&lt;ul>
&lt;li>Digital&lt;/li>
&lt;li>I also subscribed to Unlimited via Hong Kong, &lt;code>178 HKD/year&lt;/code>, about &lt;code>157.522 CNY&lt;/code>. Subscription is purchased by searching for Just Dance in the eShop.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="common-questions">
&lt;a class="heading-anchor-link" href="#common-questions">Common questions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-questions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>If Just Dance was purchased as a Hong Kong digital version, can Unlimited be purchased in another region? So far, yes. Games purchased in different regions support cross-region play, so there is no restriction. The downside is that different accounts have different game records. If you buy games across multiple regions, it can be tiring to track unless you manage it well.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Switching regions for purchases is a bit troublesome, but also fun.&lt;/li>
&lt;li>I recommend creating accounts for the regions you use most and solving it once and for all.&lt;/li>
&lt;/ul></description></item><item><title>2020 Year-End Review</title><link>https://en.1991421.cn/2021/01/16/2020/</link><pubDate>Sat, 16 Jan 2021 16:36:04 +0800</pubDate><guid>https://en.1991421.cn/2021/01/16/2020/</guid><description>&lt;blockquote>
&lt;p>Compared to previous years, 2020 saw significant growth for me, though I still have a long way to go to reach the level of the true masters.&lt;/p>
&lt;p>2021 has arrived, and looking back at the past twelve months, it&amp;rsquo;s time for some serious reflection.&lt;/p>
&lt;/blockquote>
&lt;h2 id="health">
&lt;a class="heading-anchor-link" href="#health">Health&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="health"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>The body is the foundation of everything. 2020 was the year I finally took fitness seriously—outdoor running in the first half and systematic gym training in the second.&lt;/p>
&lt;/blockquote>
&lt;ul>
&lt;li>I started as a total novice with gym equipment. By using YouTube tutorials and observing the form of regular gym-goers, I’ve finally started my professional fitness journey.&lt;/li>
&lt;li>The data is encouraging: my weight has stabilized. While I haven&amp;rsquo;t quite dropped below 70kg yet due to moderate intensity, the habit of regular exercise is now firmly rooted. The physical improvements are visible—I’m less &amp;ldquo;puffy,&amp;rdquo; and my chest muscles are taking shape.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-23-225115.jpeg"
alt="Progress in 2020"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="learning">
&lt;a class="heading-anchor-link" href="#learning">Learning&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="learning"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>I’ve refined my learning methods and settled into a mature workflow. I now use a combination of &lt;strong>Medium&lt;/strong>, &lt;strong>Twitter&lt;/strong>, &lt;strong>O&amp;rsquo;Reilly&lt;/strong>, &lt;strong>Kindle&lt;/strong>, and &lt;strong>MarginNote&lt;/strong> to cross-reference and synthesize knowledge.&lt;/li>
&lt;li>However, my reading volume is still too low (less than 10 books). As a friend bluntly put it, I lack &amp;ldquo;cultural depth.&amp;rdquo; I need to push harder here.&lt;/li>
&lt;li>The improvement I’m most proud of between 2018 and 2020 is my English. Reading is no longer a significant hurdle. My writing still needs work, but I’ve taken the first step. In 2021, I aim to reach a level where I can communicate basic ideas in writing without friction.&lt;/li>
&lt;/ul>
&lt;h2 id="technology--open-source">
&lt;a class="heading-anchor-link" href="#technology--open-source">Technology &amp;amp; Open Source&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="technology--open-source"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Technology is my livelihood; open source is my primary means of communication, exchange, and growth. I was more active in the open-source community this year than ever before.&lt;/p>
&lt;h3 id="achievements">
&lt;a class="heading-anchor-link" href="#achievements">Achievements:&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="achievements"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Developed &lt;strong>19 Alfred Workflows&lt;/strong>.&lt;/li>
&lt;li>Developed &lt;strong>3 JetBrains Plugins&lt;/strong>.&lt;/li>
&lt;li>Open-sourced several repositories on GitHub containing best practices from my work and solutions to everyday life problems.&lt;/li>
&lt;li>Continued blogging consistently. As quality and quantity improved, the blog started providing positive returns:
&lt;ul>
&lt;li>Several readers reached out via comments or email.&lt;/li>
&lt;li>I integrated &lt;strong>Google AdSense&lt;/strong> on my self-hosted blog and mirrored high-quality articles to &lt;strong>Medium&lt;/strong>. Both platforms are now generating modest income.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="life">
&lt;a class="heading-anchor-link" href="#life">Life&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="life"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>I’ve hit 30 without even realizing it. The big questions—marriage and housing—are now front and center. I can no longer avoid planning for these.&lt;/li>
&lt;/ul>
&lt;h2 id="work">
&lt;a class="heading-anchor-link" href="#work">Work&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="work"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I joined a new company in January 2020 and spent the year focusing on a single major project. Key takeaways include:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>CI Improvements&lt;/strong>: Automated MR generation and email delivery of CHANGELOGs, eliminating manual releases. Refined Lints and Hooks to ensure environment and code style consistency.&lt;/li>
&lt;li>&lt;strong>Component Library&lt;/strong>: Established a shared frontend component library to boost efficiency in common scenarios (e.g., auto-generated directories and hotkey-bound forms).&lt;/li>
&lt;li>&lt;strong>Chrome Extensions&lt;/strong>: Developed tools like a daily stand-up meeting timer/reminder.&lt;/li>
&lt;li>&lt;strong>Data Tools&lt;/strong>: Built JS utilities to convert Excel and JSON to SQL, speeding up production data fixes.&lt;/li>
&lt;li>&lt;strong>IDE Plugins&lt;/strong>: Created a JetBrains plugin to log code review issues directly within the editor.&lt;/li>
&lt;/ol>
&lt;h2 id="the-road-ahead">
&lt;a class="heading-anchor-link" href="#the-road-ahead">The Road Ahead&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-road-ahead"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Despite the successes listed above, I’m reminded of Jack Ma’s observation about why people leave jobs: they’re either underpaid or unhappy. I feel I’ve hit both points. The current environment is incredibly inefficient for me, and the frustration is compounded because the inefficiency isn&amp;rsquo;t a result of my own ability.&lt;/li>
&lt;li>At 30, it’s time to stabilize my life. I’m an adult now, and I need to act like it.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-16-173830.jpeg"
alt="Reflections at 30"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>2021, here I come!&lt;/p></description></item><item><title>Tools of the Year: 2020 Gear Review</title><link>https://en.1991421.cn/2021/01/02/2020/</link><pubDate>Sat, 02 Jan 2021 21:11:40 +0800</pubDate><guid>https://en.1991421.cn/2021/01/02/2020/</guid><description>&lt;blockquote>
&lt;p>Great tools are meant to be refined and occasionally replaced. 2020 is over, so it&amp;rsquo;s time to review the hardware and software additions I made this year and how they&amp;rsquo;ve improved my workflow and quality of life.&lt;/p>
&lt;/blockquote>
&lt;h2 id="airpods-2">
&lt;a class="heading-anchor-link" href="#airpods-2">AirPods 2&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="airpods-2"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in &lt;strong>late May&lt;/strong> for &lt;strong>997 CNY&lt;/strong>. My 1st gen AirPods had reached the end of their life—after two years, the battery barely lasted 30 minutes on a single charge. The 2nd gen was a necessary and welcome relay.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-06-16-231552.jpeg"
alt="AirPods 2"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Key Uses:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Remote meetings and calls.&lt;/li>
&lt;li>Listening to music and YouTube during commutes.&lt;/li>
&lt;li>Hands-free calls via Siri—a genuinely smooth experience.&lt;/li>
&lt;/ul>
&lt;h2 id="asus-rt-ac1900p-router">
&lt;a class="heading-anchor-link" href="#asus-rt-ac1900p-router">ASUS RT-AC1900P Router&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="asus-rt-ac1900p-router"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in &lt;strong>early September&lt;/strong> for &lt;strong>469 CNY&lt;/strong>. Compared to my previous Xiaomi router, this is a much more professional device. Signal stability, throughput, and extensibility are all significantly better.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-09-13-214054.jpeg"
alt="ASUS Router"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Key Features:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>High-performance routing for a stable home network.&lt;/li>
&lt;li>AiMesh support for expanded signal coverage in larger spaces.&lt;/li>
&lt;li>Support for custom firmware (Merlin, etc.).&lt;/li>
&lt;/ul>
&lt;h2 id="xfan-external-microphone">
&lt;a class="heading-anchor-link" href="#xfan-external-microphone">XFAN External Microphone&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xfan-external-microphone"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in &lt;strong>November&lt;/strong> for &lt;strong>153 CNY&lt;/strong>. The build quality and sound capture are excellent for the price.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-11-14-124135.jpeg"
alt="XFAN Microphone"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Main Use Case:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Serves as an &lt;a href="https://en.1991421.cn/2020/11/14/2a2d658/" target="_blank" rel="noopener">external microphone for my MacBook when used in clamshell mode&lt;/a>.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Minor Drawback:&lt;/strong>
Since this is technically a camera-mount microphone, I had to use some Blu-Tack to secure it to my desk—a simple and flexible solution.&lt;/p>
&lt;h2 id="magic-keyboard-1st-generation">
&lt;a class="heading-anchor-link" href="#magic-keyboard-1st-generation">Magic Keyboard (1st Generation)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="magic-keyboard-1st-generation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Picked up second-hand from Xianyu for &lt;strong>148 CNY&lt;/strong>. It serves as a quieter backup to my Filco 87 mechanical keyboard.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-03-114201.jpeg"
alt="Apple Magic Keyboard"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Pros:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>The layout is identical to the built-in MacBook keyboard, making for a seamless transition.&lt;/li>
&lt;li>Top-tier Apple build quality.&lt;/li>
&lt;li>Significantly quieter than a mechanical keyboard, which is essential when others are sleeping nearby.&lt;/li>
&lt;li>Personally, I prefer the AA battery design of the 1st gen over the rechargeable 2nd gen—swapping batteries is faster than waiting for a charge.&lt;/li>
&lt;/ul>
&lt;h2 id="nayo-almighty-backpack">
&lt;a class="heading-anchor-link" href="#nayo-almighty-backpack">Nayo Almighty Backpack&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="nayo-almighty-backpack"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in &lt;strong>August&lt;/strong> (large size) for &lt;strong>$48.99 USD&lt;/strong> (~317 CNY).&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-11-224454.jpeg"
alt="Nayo Almighty Backpack"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Pros:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Massive internal capacity.&lt;/li>
&lt;li>Smart storage: strap pockets for keys, an insulated zip pouch, a sunglasses hook, and a structured design that stands upright even when empty.&lt;/li>
&lt;li>Very reasonable price compared to other boutique tech bags.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Cons:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>The overall craftsmanship is decent but not exceptional; I hope to see improved materials in future iterations.&lt;/li>
&lt;/ul>
&lt;h2 id="costa-coffee-mug">
&lt;a class="heading-anchor-link" href="#costa-coffee-mug">Costa Coffee Mug&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="costa-coffee-mug"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>A gift from my department&amp;rsquo;s annual meeting (market price around &lt;strong>138 CNY&lt;/strong>).&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-06-17-222335.png"
alt="Costa Mug"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Pros:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Great aesthetic.&lt;/li>
&lt;li>Perfect size for daily tea or coffee at my desk.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Cons:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Since it&amp;rsquo;s ceramic, it has zero heat insulation.&lt;/li>
&lt;li>Not microwave-safe.&lt;/li>
&lt;/ul>
&lt;p>Despite the drawbacks, this has become my primary hydration vessel at home.&lt;/p>
&lt;h2 id="marginnote-3">
&lt;a class="heading-anchor-link" href="#marginnote-3">MarginNote 3&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="marginnote-3"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Purchased in &lt;strong>December&lt;/strong>. The Mac version was &lt;strong>251 CNY&lt;/strong> and the iOS version &lt;strong>88 CNY&lt;/strong>. I bought this to fill a gap in my digital reading workflow.&lt;/p>
&lt;p>My current system: &lt;strong>O&amp;rsquo;Reilly&lt;/strong> for technical English books, &lt;strong>Kindle&lt;/strong> for general Chinese reading, and &lt;strong>MarginNote&lt;/strong> for deep study of PDF resources. MarginNote is uniquely designed for synthesizing complex information.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-03-115129.jpeg"
alt="MarginNote 3 UI"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Pros:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Integrated mind-mapping and outlining.&lt;/li>
&lt;li>Excellent annotation and excerpt experience.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Cons:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>The app can still feel a bit unpolished. For example, PDF rendering on Mac is noticeably blurrier than in PDF Expert.&lt;/li>
&lt;li>As an indie app, it lacks the stability of big-tech offerings, but I hope the developers continue their active development (similar to Surge).&lt;/li>
&lt;/ul>
&lt;h2 id="youtube-music">
&lt;a class="heading-anchor-link" href="#youtube-music">YouTube Music&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="youtube-music"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Became a subscriber in &lt;strong>December&lt;/strong>. YouTube Music is included with a YouTube Premium membership. I recommend the India region—at &lt;strong>129 INR (~11.6 CNY) per month&lt;/strong>, it&amp;rsquo;s incredible value.&lt;/p>
&lt;p>I’ve tried QQ Music, NetEase, Apple Music, and Kugou, but I&amp;rsquo;ve settled on YouTube Music. Why?&lt;/p>
&lt;ol>
&lt;li>I&amp;rsquo;m a heavy YouTube user, so the ecosystem synergy is perfect.&lt;/li>
&lt;li>The UI is clean, ad-free, and focuses on music rather than distracting social comments.&lt;/li>
&lt;li>The library is surprisingly comprehensive, even for Chinese songs.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-03-115421.jpeg"
alt="YouTube Music App"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Pros:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Massive global library.&lt;/li>
&lt;li>Easy switching between audio and official music videos.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Cons:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Cannot be directly summoned via Siri, meaning my HomePod has become a simple external speaker rather than a smart one.&lt;/li>
&lt;li>No official Mac desktop app (requires browser or third-party wrappers).&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Good tools solve real problems and are always worth the investment.&lt;/li>
&lt;li>However, more tools can lead to more clutter. Choose what fits your hand and your workflow naturally.&lt;/li>
&lt;li>2020 was a year of global upheaval. Whether we spent it productively or simply drifted through it is a question only we can answer. Here’s to even more progress in 2021.&lt;/li>
&lt;/ul></description></item><item><title>Third-Party Services Used by My Blog</title><link>https://en.1991421.cn/2021/01/02/blog-deployment-third-party-services/</link><pubDate>Sat, 02 Jan 2021 13:34:58 +0800</pubDate><guid>https://en.1991421.cn/2021/01/02/blog-deployment-third-party-services/</guid><description>&lt;blockquote>
&lt;p>During the New Year holiday, I spent some time deploying my personal English blog site. It uses the same services and tech as my Chinese blog; the only difference is the content. So this is also a review of the vendor services used in my blog deployment, summarized here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="hexojs--static-blog-framework">
&lt;a class="heading-anchor-link" href="#hexojs--static-blog-framework">Hexojs — static blog framework&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="hexojs--static-blog-framework"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Using Hexo: posts are written in Markdown and compiled to static HTML, so it’s fast to serve. Downsides: as content grows, build times slow. With 300+ Chinese posts, a full build took ~8 minutes.&lt;/p>
&lt;p>This remains unresolved for now.&lt;/p>
&lt;h2 id="theme-next">
&lt;a class="heading-anchor-link" href="#theme-next">theme-next&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="theme-next"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I use &lt;a href="https://theme-next.iissnan.com/" target="_blank" rel="noopener">theme-next&lt;/a>. I customize parts, but keep custom templates/CSS separate to ease framework/theme upgrades.&lt;/p>
&lt;h2 id="vultr">
&lt;a class="heading-anchor-link" href="#vultr">&lt;del>Vultr&lt;/del>&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="vultr"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I deployed static pages on &lt;code>Vultr Japan, $6/mo&lt;/code> — decent speed from mainland China.&lt;/p>
&lt;p>Now migrated to Tencent Cloud.&lt;/p>
&lt;h2 id="github">
&lt;a class="heading-anchor-link" href="#github">GitHub&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="github"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Source code is hosted on GitHub; CD uses GitHub Actions. It’s stable and free.&lt;/p>
&lt;h2 id="telegram-bot">
&lt;a class="heading-anchor-link" href="#telegram-bot">Telegram Bot&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="telegram-bot"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I added notifications for deployments; Telegram is ideal. Using &lt;a href="https://github.com/appleboy/telegram-action" target="_blank" rel="noopener">appleboy/telegram-action&lt;/a>.&lt;/p>
&lt;h3 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The token is obtained via &lt;code>@BotFather&lt;/code>. The token format is &lt;code>1234567890:ABCDEFGHIJKLMN&lt;/code>.&lt;/li>
&lt;li>The URL to get the chatId using the token is &lt;code>https://api.telegram.org/bot1234567890:ABCDEFGHIJKLMN/getUpdates&lt;/code>. If the result says OK but the &lt;code>result&lt;/code> array is empty, send a message to the bot and try again.&lt;/li>
&lt;/ol>
&lt;h2 id="lets-encrypt">
&lt;a class="heading-anchor-link" href="#lets-encrypt">Let’s Encrypt&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="lets-encrypt"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Most sites are on SSL now; I use Let’s Encrypt because it’s free and Certbot automates issuance/renewal.&lt;/p>
&lt;p>Since I host both Chinese/English sites and an image host, I applied for a wildcard cert.&lt;/p>
&lt;h2 id="gittalk">
&lt;a class="heading-anchor-link" href="#gittalk">GitTalk&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="gittalk"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Comment system based on GitHub Issues — convenient.&lt;/p>
&lt;h2 id="algolia">
&lt;a class="heading-anchor-link" href="#algolia">Algolia&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="algolia"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Search: fast, good UX, and free tier.&lt;/p>
&lt;h2 id="google-adsense">
&lt;a class="heading-anchor-link" href="#google-adsense">Google AdSense&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="google-adsense"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Hosting isn’t free; AdSense may offset costs. Ads do slow page loads, admittedly.&lt;/p>
&lt;h2 id="google-search-console">
&lt;a class="heading-anchor-link" href="#google-search-console">Google Search Console&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="google-search-console"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Webmaster tools:&lt;/p>
&lt;ol>
&lt;li>SEO for Google: submit sitemaps for crawling&lt;/li>
&lt;li>Monitor site traffic&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>That’s the stack of third‑party services behind my blog. Even a small blog ties together quite a lot of tech.&lt;/p></description></item><item><title>JSON vs XML Comparison</title><link>https://en.1991421.cn/2020/12/20/json-vs-xml/</link><pubDate>Sun, 20 Dec 2020 22:52:12 +0800</pubDate><guid>https://en.1991421.cn/2020/12/20/json-vs-xml/</guid><description>&lt;blockquote>
&lt;p>In today&amp;rsquo;s frontend-backend separation era, backend APIs typically provide data in JSON format, but it&amp;rsquo;s important to understand this is just one format option among many, such as XML. Not all service communications or frontend-backend interactions use JSON - some services explicitly use XML instead of JSON. Therefore, understanding the differences between these two formats is crucial for making appropriate choices based on requirements.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-12-21-220255.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="definitions">
&lt;a class="heading-anchor-link" href="#definitions">Definitions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="definitions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Understanding a technology starts with its name and pronunciation. For detailed JSON and XML introductions, refer to Wikipedia.&lt;/p>
&lt;p>JSON：JavaScript Object Notation&lt;/p>
&lt;pre>&lt;code>- Pronunciation: JAY-sawn
&lt;/code>&lt;/pre>
&lt;p>XML：E&lt;strong>x&lt;/strong>tensible &lt;strong>M&lt;/strong>arkup &lt;strong>L&lt;/strong>anguage&lt;/p>
&lt;pre>&lt;code> - Pronunciation: /ˌeks em ˈel/
&lt;/code>&lt;/pre>
&lt;h3 id="why-isnt-xml-called-eml">
&lt;a class="heading-anchor-link" href="#why-isnt-xml-called-eml">Why isn&amp;rsquo;t XML called EML?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-isnt-xml-called-eml"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Curious about this, I Googled and found a related &lt;a href="https://softwareengineering.stackexchange.com/questions/88405/why-is-xml-not-called-eml" target="_blank" rel="noopener">question&lt;/a>. The relatively accurate answer is that when determining XML, committee members proposed their suggested full names and abbreviations, one of which was &lt;code>XML：Extensible Markup Language&lt;/code>. Based on voting results, &lt;code>XML&lt;/code> was finalized. The X represents anything, special, cool, and in the mathematical field, it represents variables, unknowns, possibilities.&lt;/p>
&lt;p>No wonder naming has always been a &lt;em>challenge&lt;/em> in the coding field.&lt;/p>
&lt;h2 id="json-vs-xml">
&lt;a class="heading-anchor-link" href="#json-vs-xml">JSON vs XML&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="json-vs-xml"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In practical development, choosing a data format requires understanding the differences. Here are the key differences:&lt;/p>
&lt;ul>
&lt;li>JSON has smaller &lt;code>size&lt;/code> compared to XML, with faster &lt;code>transmission speed&lt;/code> and &lt;code>parsing speed&lt;/code>&lt;/li>
&lt;li>JSON doesn&amp;rsquo;t support &lt;code>comments&lt;/code>, while XML does&lt;/li>
&lt;li>JSON has explicit &lt;code>data types&lt;/code> (string, boolean, number, object, array, null) - 6 data types, while XML has no restrictions on data types&lt;/li>
&lt;li>XML supports &lt;code>namespaces&lt;/code>, while JSON does not&lt;/li>
&lt;/ul>
&lt;p>I personally agree with a friend&amp;rsquo;s &lt;a href="https://www.zhihu.com/question/25636060" target="_blank" rel="noopener">answer on Zhihu&lt;/a>&lt;/p>
&lt;blockquote>
&lt;p>JSON&amp;rsquo;s existence is a typical case of 20% functionality solving 80% of requirements.
Why not use XML? Because 80% of its features you don&amp;rsquo;t need, but when you do need them, you&amp;rsquo;ll understand that only XML can do it, JSON cannot.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;em>Note: Both XML &amp;amp; JSON are case-sensitive.&lt;/em>&lt;/p>
&lt;h2 id="json-serialization-and-deserialization">
&lt;a class="heading-anchor-link" href="#json-serialization-and-deserialization">JSON Serialization and Deserialization&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="json-serialization-and-deserialization"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Understanding JSON and XML requires understanding serialization issues, which can be tricky.&lt;/p>
&lt;p>Using JSON as the data format and Java and JavaScript as languages, here are some points to watch out for - if you don&amp;rsquo;t pay attention, they can become pitfalls.&lt;/p>
&lt;h3 id="java">
&lt;a class="heading-anchor-link" href="#java">Java&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="java"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>Classes implementing the &lt;code>Serializable&lt;/code> interface must provide a &lt;code>public no-argument constructor&lt;/code>. If there&amp;rsquo;s no no-argument constructor, a runtime exception will be thrown: &lt;code>java.io.InvalidClassException&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Objects transmitted in MVC controllers &lt;code>don't need&lt;/code> to implement Serializable because controllers transmit not objects but bind objects to network packets, not involving serialization and deserialization&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Commonly used Jackson and Gson libraries &lt;code>don't require&lt;/code> target classes to implement the Serializable interface during serialization and deserialization&lt;/p>
&lt;/li>
&lt;li>
&lt;p>In serialized class files, you often see the serialVersionUID variable&lt;/p>
&lt;p>serialVersionUID is for controlling version compatibility. If we consider bean modifications backward compatible, we don&amp;rsquo;t change it; otherwise, we increase the value. If serialVersionUID&amp;rsquo;s value isn&amp;rsquo;t explicitly defined, Java automatically generates it based on class details. If class source code is modified and recompiled, serialVersionUID might change. The default value of serialVersionUID depends on Java compiler implementation, so for safety, manual declaration is better.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="javascript">
&lt;a class="heading-anchor-link" href="#javascript">JavaScript&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="javascript"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>Objects after JSON.parse have undefined getter methods&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">class&lt;/span> &lt;span class="nx">Person&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">firstname&lt;/span>: &lt;span class="kt">string&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">lastname&lt;/span>: &lt;span class="kt">string&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">get&lt;/span> &lt;span class="nx">fullname&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">firstname&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39; &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">lastname&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">p&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">Person&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">p&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">firstname&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;alan&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">p&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">lastname&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;he&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">p&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">fullname&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// alan he
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">p2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">JSON&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;{&amp;#34;firstname&amp;#34;:&amp;#34;alan&amp;#34;,&amp;#34;lastname&amp;#34;:&amp;#34;he&amp;#34;}&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="kr">as&lt;/span> &lt;span class="nx">Person&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">p2&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">fullname&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// undefined
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Deserialized objects don&amp;rsquo;t have methods defined in the class, so you need to instantiate a class object, for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">userJSONObj&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">JSON&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;{&amp;#34;firstname&amp;#34;:&amp;#34;alan&amp;#34;,&amp;#34;lastname&amp;#34;:&amp;#34;he&amp;#34;}&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">p2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">Person&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">userJSONObj&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;firstname&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="nx">userJSONObj&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;lastname&amp;#39;&lt;/span>&lt;span class="p">]);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">p2&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">fullname&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// alan he
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>[&lt;a href="https://stackoverflow.com/questions/43367692/typescript-method-on-class-undefined" target="_blank" rel="noopener">Typescript method on class undefined&lt;/a>](&lt;a href="https://stackoverflow.com/questions/12702548/constructor-overload-in-typescript" target="_blank" rel="noopener">https://stackoverflow.com/questions/12702548/constructor-overload-in-typescript&lt;/a>)&lt;/li>
&lt;li>&lt;a href="https://my.oschina.net/wangmengjun/blog/1588096" target="_blank" rel="noopener">Serializable and Externalizable Analysis&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Relearning Regular Expressions</title><link>https://en.1991421.cn/2020/11/26/regex-intensive-training/</link><pubDate>Thu, 26 Nov 2020 22:01:38 +0800</pubDate><guid>https://en.1991421.cn/2020/11/26/regex-intensive-training/</guid><description>&lt;blockquote>
&lt;p>While writing an Alfred workflow, I hit many text‑processing problems and doubled down on regex. Although every language course touches regex early, my skills were rusty. I took the chance to study properly; here are my takeaways.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-11-28-161744.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="why-regex-matters">
&lt;a class="heading-anchor-link" href="#why-regex-matters">Why regex matters&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-regex-matters"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Regex is the Swiss army knife of text processing — unavoidable for many tasks. For example, extracting multiple metadata fields from Markdown is quickest with regex.&lt;/p>
&lt;h2 id="the-right-mental-model">
&lt;a class="heading-anchor-link" href="#the-right-mental-model">The right mental model&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-right-mental-model"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I avoided regex because I feared “hard parts” like lookarounds. The fix was reframing:&lt;/p>
&lt;ul>
&lt;li>Assertions match positions (zero‑width); lookahead/lookbehind choose direction; positive/negative choose condition (must match vs. must not).&lt;/li>
&lt;li>Metacharacters match content; assertions match positions; add in grouping, repetition, and greediness/laziness — that’s most of it.&lt;/li>
&lt;/ul>
&lt;p>Don’t fear it; practice deliberately; then apply correctly in the right scenarios.&lt;/p>
&lt;h2 id="recommended-resources">
&lt;a class="heading-anchor-link" href="#recommended-resources">Recommended resources&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="recommended-resources"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://deerchao.cn/tutorials/regex/regex.htm" target="_blank" rel="noopener">Regular Expressions 30-Minute Primer&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://alf.nu/RegexGolf" target="_blank" rel="noopener">Regex Golf - Regular Expression Challenge Game&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://learning.oreilly.com/library/view/regex-quick-syntax/9781484238769/" target="_blank" rel="noopener">Regex Quick Syntax Reference&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://regex101.com/" target="_blank" rel="noopener">Regex Tool&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://regexper.com/" target="_blank" rel="noopener">Regex Visualization Tool&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>With the mindset corrected and concepts organized, I can finally use regex effectively. As with JS itself: understand it properly, practice intentionally, reflect in use — familiarity grows into mastery.&lt;/p></description></item><item><title>Buying Safari Online (O'Reilly) Membership via ACM</title><link>https://en.1991421.cn/2020/11/22/safari-online/</link><pubDate>Sun, 22 Nov 2020 18:36:50 +0800</pubDate><guid>https://en.1991421.cn/2020/11/22/safari-online/</guid><description>&lt;blockquote>
&lt;p>Our company dropped the O&amp;rsquo;Reilly Safari Online subscription. To keep learning freely, I needed a personal workaround.&lt;/p>
&lt;/blockquote>
&lt;p>The official price is steep: “Safari Books Online costs $39 per month or $399 per year.” If you can afford it, great; if not, read on.&lt;/p>
&lt;p>One alternative is to join ACM for $25/year and use that to access Safari. That’s the route I took.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-11-22-185639.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="register-for-acm">
&lt;a class="heading-anchor-link" href="#register-for-acm">Register for ACM&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="register-for-acm"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Sign up here: &lt;a href="https://services.acm.org/public/qj/proflevel/proflevel_control.cfm?level=3&amp;amp;country=China&amp;amp;form_type=Professional&amp;amp;promo=LEVEL" target="_blank" rel="noopener">https://services.acm.org/public/qj/proflevel/proflevel_control.cfm?level=3&amp;country=China&amp;form_type=Professional&amp;promo=LEVEL&lt;/a>&lt;/li>
&lt;li>Choose the lowest tier ($25 ≈ 164.51 RMB).&lt;/li>
&lt;li>Pay via PayPal.&lt;/li>
&lt;li>After payment you’ll be prompted to finish registration. Complete the forms and save the generated username/password.&lt;/li>
&lt;li>Check membership status at &lt;a href="https://myacm.acm.org" target="_blank" rel="noopener">https://myacm.acm.org&lt;/a>.&lt;/li>
&lt;li>ACM emails renewal reminders annually; renew manually for the same $25 rate.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-11-22-185016.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="log-in-to-safari-online">
&lt;a class="heading-anchor-link" href="#log-in-to-safari-online">Log in to Safari Online&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="log-in-to-safari-online"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Enter your ACM email (with the &lt;code>@acm.org&lt;/code> suffix). Safari redirects to ACM’s login page.&lt;/li>
&lt;li>Use the same username &lt;strong>without&lt;/strong> the &lt;code>@acm.org&lt;/code> suffix; the password is unchanged.&lt;/li>
&lt;li>Works across iOS, iPad, and the web.&lt;/li>
&lt;/ul>
&lt;h3 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>O’Reilly doesn’t limit device count, so multiple people can share the same account (though sharing may violate terms—use judgment).&lt;/li>
&lt;/ul>
&lt;h2 id="reference">
&lt;a class="heading-anchor-link" href="#reference">Reference&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="reference"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://learning.acm.org/faq/oreilly-faqs" target="_blank" rel="noopener">https://learning.acm.org/faq/oreilly-faqs&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>For $25 a year you gain full access to O’Reilly’s library—not bad.&lt;/li>
&lt;li>I’ve moved away from paper books; they’re bulky and hard to manage. Kindle + O’Reilly cover my needs across languages and topics.&lt;/li>
&lt;/ul></description></item><item><title>A Loving Inn in Dali — Guanyuan</title><link>https://en.1991421.cn/2020/11/08/guanyuan-inn/</link><pubDate>Sun, 08 Nov 2020 22:19:21 +0800</pubDate><guid>https://en.1991421.cn/2020/11/08/guanyuan-inn/</guid><description>&lt;blockquote>
&lt;p>I recently “sneaked” off to Dali. While keeping up with work, I also switched into a mode of appreciating Dali and Erhai Lake.&lt;/p>
&lt;p>I expected just to enjoy the scenery, but the inn I stayed at was so wonderful that it added many delightful elements to the trip. I left determined to stay &lt;a href="https://www.airbnb.cn/rooms/41162436?translate_ugc=false&amp;amp;source_impression_id=p3_1604844748_jlIoUDW%2FRQGtBUQu" target="_blank" rel="noopener">here&lt;/a> again next time!&lt;/p>
&lt;p>A few words to record this goodness and to praise the lovely people who run this place.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;em>Not an ad — just heartfelt impressions.&lt;/em>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-11-08-223842.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="beautiful-scenery">
&lt;a class="heading-anchor-link" href="#beautiful-scenery">Beautiful Scenery&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="beautiful-scenery"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-11-08-223145.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ul>
&lt;li>The inn overflows with lush greenery — genuine garden art.&lt;/li>
&lt;li>From the rooftop you can see the Cangshan Mountains on one side and Erhai Lake on the other, with a sky full of stars overhead. I went up nearly every day, paired my phone to a Bluetooth speaker, and soaked in the views with music.&lt;/li>
&lt;/ul>
&lt;h2 id="delicious-food">
&lt;a class="heading-anchor-link" href="#delicious-food">Delicious Food&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="delicious-food"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Breakfast is complimentary: authentic rice noodles and other noodles each morning, plus my favorite corn cakes.&lt;/li>
&lt;li>Lunch is a communal meal for 30 RMB per person. Everyone eats together, chats, laughs, and unwinds.&lt;/li>
&lt;li>Dinner can be shared as well, or you can order your own feast like barbecue at market prices. I skipped it to explore the old town’s food.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-11-08-225518.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-11-08-225550.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="hosts-who-love-life">
&lt;a class="heading-anchor-link" href="#hosts-who-love-life">Hosts Who Love Life&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="hosts-who-love-life"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If the owners didn’t genuinely love life, the inn couldn’t feel like this. That was my first impression, and chatting with them confirmed it.&lt;/p>
&lt;p>Examples:&lt;/p>
&lt;ul>
&lt;li>The “uncle” (one of the hosts) tends every plant himself.&lt;/li>
&lt;li>From bedding to décor, everything is chosen to keep guests (and themselves) comfortable.&lt;/li>
&lt;li>Even the rice is carefully sourced. I’m not a foodie, yet I liked it so much that I ran to the kitchen to check the brand — later bought it on Taobao.&lt;/li>
&lt;li>&amp;hellip;&lt;/li>
&lt;/ul>
&lt;h2 id="adorable-animals">
&lt;a class="heading-anchor-link" href="#adorable-animals">Adorable Animals&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="adorable-animals"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Alongside the lovely hosts are many pets. In just a few days I somehow stopped being afraid of cats. My favorite remains the dog — especially their Border Collie, Jasmine.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-11-08-225839.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>When I checked out, I told the owner the stay far exceeded expectations. Airbnb can’t convey these human touches, and the inn doesn’t advertise aggressively.&lt;/li>
&lt;li>I watched the hosts greet every guest warmly, sip tea, strum guitars, cuddle cats and dogs — an enviable, inspiring rhythm of life. This is what living looks like.&lt;/li>
&lt;li>Think of this as a small shout-out for a genuinely wonderful place.&lt;/li>
&lt;/ul></description></item><item><title>The 7 Habits of Highly Effective People - Book Review</title><link>https://en.1991421.cn/2020/11/07/702712000000/</link><pubDate>Sat, 07 Nov 2020 23:13:11 +0800</pubDate><guid>https://en.1991421.cn/2020/11/07/702712000000/</guid><description>&lt;blockquote>
&lt;p>During a pleasant work trip, I read a few books, including &lt;a href="https://book.douban.com/subject/5325618/" target="_blank" rel="noopener">The 7 Habits of Highly Effective People&lt;/a>. I have some personal reflections and thoughts on these seven habits.&lt;/p>
&lt;p>While marking this down, I also encourage myself to improve and adjust continually.&lt;/p>
&lt;/blockquote>
&lt;img src="https://static.1991421.cn/2020/2020-11-07-231616.jpeg" style="zoom:50%;" />
&lt;h2 id="be-proactive">
&lt;a class="heading-anchor-link" href="#be-proactive">Be Proactive&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="be-proactive"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I think I am at least proactive when it comes to learning. Looking back at the past year, I feel I have made some gains in&lt;/p>
&lt;ol>
&lt;li>Reading, especially in English, has improved, resulting in a reduction in reading difficulties.&lt;/li>
&lt;li>Communication and consulting: I&amp;rsquo;m not a closed-off person due to my personality. So, I often like to talk, share, ask questions, and engage in discussions.&lt;/li>
&lt;/ol>
&lt;p>Therefore, I think I&amp;rsquo;m doing pretty well with this habit, but there&amp;rsquo;s still room for improvement.&lt;/p>
&lt;h2 id="put-first-things-first">
&lt;a class="heading-anchor-link" href="#put-first-things-first">Put First Things First&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="put-first-things-first"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Reflecting on this habit, I can only say that I&amp;rsquo;m making progress but still not doing well enough.&lt;/p>
&lt;p>For example, at work, I often want to do everything well, but this often results in everything being half-finished or falling short of my expectations.&lt;/p>
&lt;p>In life, the problem is less pronounced but still exists. The result is that nothing is done well, leading to a lack of a sense of accomplishment and rewards.&lt;/p>
&lt;h2 id="begin-with-the-end-in-mind">
&lt;a class="heading-anchor-link" href="#begin-with-the-end-in-mind">Begin with the End in Mind&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="begin-with-the-end-in-mind"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>This habit is about not forgetting your original intention. I think I&amp;rsquo;ve done well in this regard and always had this understanding. Many programmers are more like wage earners, who code for money without much joy. But if you love it, it&amp;rsquo;s different. The money is just an added bonus; the real joy comes from the love of programming.&lt;/p>
&lt;p>I&amp;rsquo;m also a programmer, but my motivation is love. To this day, I still love programming. I hope to use programming to solve real problems and meet others&amp;rsquo; or my own needs. This is my original intention, and it won&amp;rsquo;t change.&lt;/p>
&lt;h2 id="think-win-win">
&lt;a class="heading-anchor-link" href="#think-win-win">Think Win-Win&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="think-win-win"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I think I&amp;rsquo;ve done well with this habit, as I often don&amp;rsquo;t see personal interests as conflicting with others. Many times, a win-win situation is possible.&lt;/p>
&lt;p>Recently, I&amp;rsquo;ve had some thoughts on this in my work. If you always set yourself against others, you may lose, even if it&amp;rsquo;s just losing a relationship. But if you can consider others&amp;rsquo; interests while considering your own, your actions and final rewards will extend beyond just yourself, and everyone will gain.&lt;/p>
&lt;h2 id="seek-first-to-understand-then-to-be-understood">
&lt;a class="heading-anchor-link" href="#seek-first-to-understand-then-to-be-understood">Seek First to Understand, Then to Be Understood&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="seek-first-to-understand-then-to-be-understood"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The essence of this habit is listening. Indeed, listening to others&amp;rsquo; ideas can often solve some of your own puzzles.&lt;/p>
&lt;p>I think I haven&amp;rsquo;t done enough in this regard, especially in the past year, where I&amp;rsquo;ve been a bit closed off. I need to listen more and communicate more.&lt;/p>
&lt;h2 id="synergize">
&lt;a class="heading-anchor-link" href="#synergize">Synergize&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="synergize"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The benefit of synergy is that 1+1&amp;gt;2. For example, in my current work, the people I deal with and the communication needed—sometimes, it can be very simple if others can cooperate well. However, some people only focus on their own interests without considering the overall benefit, resulting in losses for everyone.&lt;/p>
&lt;p>But from another perspective, if we can unite, everyone can be efficient, and achieve more. Why not?&lt;/p>
&lt;h2 id="sharpen-the-saw">
&lt;a class="heading-anchor-link" href="#sharpen-the-saw">Sharpen the Saw&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="sharpen-the-saw"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Yes, no one is always right. Therefore, we often need to adjust ourselves. All habits, as do the methodologies behind them, need constant updating. We can only ensure that we remain relatively excellent by constantly updating, allowing us to handle the ever-changing external environment better.&lt;/p>
&lt;h2 id="at-the-end">
&lt;a class="heading-anchor-link" href="#at-the-end">At the end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="at-the-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>These are just a few notes expressing some feelings after reading this book.&lt;/li>
&lt;/ul></description></item><item><title>Book Notes: Life’s Moat (《人生护城河》)</title><link>https://en.1991421.cn/2020/10/26/life-moat-book-review/</link><pubDate>Mon, 26 Oct 2020 21:38:19 +0800</pubDate><guid>https://en.1991421.cn/2020/10/26/life-moat-book-review/</guid><description>&lt;blockquote>
&lt;p>I decided to take a trip over the weekend. Four long hours in the air and I just couldn’t sleep, so I started reading this book, &lt;a href="https://book.douban.com/subject/34451688/" target="_blank" rel="noopener">人生护城河&lt;/a>, and finished it in a few hours. Leaving a trace for myself, I’m jotting down some quick reflections here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-10-27-095103.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="love-writing">
&lt;a class="heading-anchor-link" href="#love-writing">Love Writing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="love-writing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>It’s been 6.5 years since I graduated. How many blog posts do I have? 311. That’s not many. Compared with the author, who publishes daily, the gap isn’t just the number of posts; it reflects the thinking and reading behind them.&lt;/p>
&lt;p>I agree with his view: love writing, stick with it, and write bravely. I’ve gained a lot from writing in practice:&lt;/p>
&lt;ul>
&lt;li>Because I struggled to find writing topics, I started thinking about technical problems at work, summarized them, practiced them, and then wrote about them in blogs.&lt;/li>
&lt;li>Because of the blog output, the cost of explaining issues to team members or netizens has been reduced.&lt;/li>
&lt;li>Because I wanted to present technical articles more systematically and accurately, I read more relatively authoritative books.&lt;/li>
&lt;li>Because I wrote a few high-quality blog posts, I made some excellent friends.&lt;/li>
&lt;li>And so on&lt;/li>
&lt;/ul>
&lt;p>Writing has many benefits. Since it’s so worthwhile, why not keep at it? I do have the habit, but the frequency is too low — in part because I don’t read enough, solve enough problems, or summarize enough.&lt;/p>
&lt;p>So I need to reflect, summarize, and strengthen both the writing and the habits behind it.&lt;/p>
&lt;p>His successful practice is a strong proof to me: you must keep writing.&lt;/p>
&lt;h2 id="three-income-streams">
&lt;a class="heading-anchor-link" href="#three-income-streams">Three Income Streams&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="three-income-streams"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Money is unavoidable, but I’ve often managed it passively or muddled through.&lt;/p>
&lt;p>I agree with the plan for multiple income sources:&lt;/p>
&lt;ol>
&lt;li>Salary&lt;/li>
&lt;li>Second income (side projects)&lt;/li>
&lt;li>Investments&lt;/li>
&lt;/ol>
&lt;p>For ordinary wage earners, indeed, a single source of income and diverse uncertain expenses are destined to make individuals stretched thin. To solve this problem, we must be brave, face this problem squarely, and intentionally move in the right direction to gradually improve the situation. Otherwise, when will we stop being poor, and when will we achieve financial freedom?&lt;/p>
&lt;p>For me, the plan is:&lt;/p>
&lt;ul>
&lt;li>Grow salary by improving professional skills.&lt;/li>
&lt;li>Build a second income via blogging, Medium, open source, and paid plugins. Thanks to affiliate links on the blog, I’ve made about $20 — not enough to cover VPS costs, but the model is healthy and sustainable. Still, content quantity and quality are the real key.&lt;/li>
&lt;li>As for investing, I started with stocks last year. No losses so far, but no real gains either. The reason is simple: I lack investment knowledge — haven’t even read a single book. So back to the old advice: read more.&lt;/li>
&lt;/ul>
&lt;h2 id="forget-it--play-to-your-strengths">
&lt;a class="heading-anchor-link" href="#forget-it--play-to-your-strengths">Forget It — Play to Your Strengths&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="forget-it--play-to-your-strengths"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>This point in the book really hit home. Personally, I love tinkering with software and gadgets, and I love sharing. For a long time I saw these traits as flaws, and my family did too — which made me unhappy. But thinking back, because I tinker, I developed an instinct for user experience that still influences my work. Because I love gadgets, people ask me for help and I’ve deepened and expanded friendships. Because I love sharing, I’ve helped and met many people. I need to admit these traits shaped me. If they take time, why not invest that time?&lt;/p>
&lt;p>We often try to learn from others, change ourselves, and fix our weaknesses. But some weaknesses are hard to fix. Why not shift the mindset, amplify and showcase our strengths, and sidestep weaknesses where reasonable?&lt;/p>
&lt;p>I often think: our differences come from our strengths, weaknesses, and quirks. If we truly changed them all, wouldn’t we all become the same?&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I suspect the author, Zhang Hui, has achieved financial freedom — built on excellence, which in turn comes from excellent habits.&lt;/p>
&lt;p>So: change yourself, become better, and once you identify the right things, keep doing them. Quantity becomes quality. If you keep doing the right things and keep improving, how bad could life be? Looking back when we’re old, how much regret would there be?&lt;/p></description></item><item><title>Review: AFTERSHOKZ Bone-Conduction Headphones</title><link>https://en.1991421.cn/2020/10/08/68362704/</link><pubDate>Thu, 08 Oct 2020 14:57:14 +0800</pubDate><guid>https://en.1991421.cn/2020/10/08/68362704/</guid><description>&lt;blockquote>
&lt;p>A family member bought the &lt;a href="https://item.jd.com/16636418552.html?cu=true&amp;amp;utm_source=norefer&amp;amp;utm_medium=cpc&amp;amp;utm_campaign=t_281_20170818001&amp;amp;utm_term=_0_ce4e8f59e3be49989f3ca9a561d3f8fa" target="_blank" rel="noopener">AFTERSHOKZ AS650 Air bone-conduction headphones&lt;/a>. I’d never used this style before, so I borrowed them for a while. Here’s what stood out—useful if you’re deciding between bone conduction and traditional earbuds.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-10-08-150516.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Novel design. It’s fundamentally different from in-ear or over-ear headphones, great for people who dislike having tips in their ears or pressure on their head.&lt;/li>
&lt;li>Decent build quality. Nothing mind-blowing at the ~¥1,000 price point, but it feels well-made.&lt;/li>
&lt;li>Comfortable. There’s no ear canal contact and the unit weighs only about 30 g, so there’s virtually no fatigue.&lt;/li>
&lt;/ul>
&lt;h2 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Sound quality. That’s half the equation (the other half being battery life). These fall short of my AirPods 2, and they’re nowhere near my Bose 700s.&lt;/li>
&lt;li>Experience polish. This model doesn’t auto-pause when you take it off. After getting used to Apple’s ecosystem, that feels clunky. Forget about tight integration with voice assistants or companion apps.&lt;/li>
&lt;li>Price. Bone-conduction tech is mature and this is a domestic brand. I don’t see ¥1,000 worth of value here.&lt;/li>
&lt;/ul>
&lt;h2 id="verdict">
&lt;a class="heading-anchor-link" href="#verdict">Verdict&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="verdict"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>At this price, unless you specifically need bone conduction, I’d stick with in-ear options from Xiaomi, Huawei, Apple, etc. AFTERSHOKZ touts “safer” listening because your ears stay open, but with the volume high enough you’ll still miss conversations around you. Long-term headphone use also carries the same hearing risks.&lt;/p>
&lt;p>If you’re curious or simply like trying new gadgets, go for it. For most buyers, other options offer better value.&lt;/p></description></item><item><title>Weekend Reading: Two Reports</title><link>https://en.1991421.cn/2020/09/21/read-two-reports/</link><pubDate>Mon, 21 Sep 2020 09:24:09 +0800</pubDate><guid>https://en.1991421.cn/2020/09/21/read-two-reports/</guid><description>&lt;blockquote>
&lt;p>I spent part of the weekend reading two reports: the &lt;strong>2019–2020 China Developer Survey&lt;/strong> and &lt;strong>InfoQ’s 2020 China Technology Development White Paper&lt;/strong>. A few quick notes for myself.&lt;/p>
&lt;/blockquote>
&lt;h2 id="lifelong-learning">
&lt;a class="heading-anchor-link" href="#lifelong-learning">Lifelong learning&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="lifelong-learning"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>One data point stunned me: &lt;em>nearly 60% of developers study more than six hours each week&lt;/em>. I’ve followed this survey since around 2015, and I don’t remember seeing that metric before. It’s sobering. Companies can always hire a motivated newcomer who’s sharp and cheaper—why keep the jaded veteran who’s stopped growing? The world keeps specializing; to avoid obsolescence (and to stay in control of our own careers), continuous learning is the only option.&lt;/p>
&lt;p>Six hours is a lot when you consider how many teams still grind through 996/997 schedules. Yet many developers still carve out time. If we’re the ones who don’t, we’ll fall behind.&lt;/p>
&lt;h2 id="open-source-contributions">
&lt;a class="heading-anchor-link" href="#open-source-contributions">Open source contributions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="open-source-contributions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The survey also shows how weak domestic open-source contributions remain. Aside from a few leaders—Alibaba, Huawei—there isn’t much. I’ve written code for many years and still contribute far too little. I need to fix that. Open source is the backbone of our industry. It’s a chance to learn from top engineers, sharpen skills, and give back. Everyone wins.&lt;/p>
&lt;h2 id="t-shaped-skills">
&lt;a class="heading-anchor-link" href="#t-shaped-skills">T-shaped skills&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="t-shaped-skills"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Those reports mention countless technologies—blockchain, deep learning—that I only vaguely recognize. It’s a sign I’ve been too narrow lately. I used to check GitHub Trends regularly and tinker with new stacks. That curiosity matters, even if I’m focused on application-layer work. Breadth informs architectural choices and helps pick the right tool for the job. The goal is to be T-shaped: deep in one area, competent across many.&lt;/p>
&lt;h2 id="globalization">
&lt;a class="heading-anchor-link" href="#globalization">Globalization&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="globalization"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Another theme: globalization. Countries compete, individuals compete. In the past we measured ourselves against colleagues or friends; digital connectivity removed those boundaries. Now we’re competing with everyone, everywhere. That’s both exciting and stressful.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>If you’re not moving forward, you’re sliding backward. Today’s pace doesn’t leave room to coast. The competition is intense, but there’s joy in staying sharp—embrace it.&lt;/p></description></item><item><title>My iPad App List</title><link>https://en.1991421.cn/2020/09/18/ipad/</link><pubDate>Fri, 18 Sep 2020 13:54:36 +0800</pubDate><guid>https://en.1991421.cn/2020/09/18/ipad/</guid><description>&lt;blockquote>
&lt;p>Mac and iPhone are the main productivity devices in actual work and life, while the iPad ranks second in my toolchain. However, it is also important. My positioning for the iPad is reading, so I chose the mini size.&lt;/p>
&lt;p>Here, I will organize the Apps installed on the iPad for record purposes, and maybe it can also provide some references for some friends.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-07-25-001531.jpeg"
alt="https://static.1991421.cn/2024/2024-07-25-001531.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="app-list">
&lt;a class="heading-anchor-link" href="#app-list">App List&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="app-list"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="youtube">
&lt;a class="heading-anchor-link" href="#youtube">YouTube&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="youtube"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Video&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Paid/Subscription&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: Rich and comprehensive videos, suitable for both learning and entertainment&lt;/li>
&lt;/ul>
&lt;h3 id="podcasts">
&lt;a class="heading-anchor-link" href="#podcasts">Podcasts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="podcasts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Audiobooks&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Free&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: None&lt;/li>
&lt;/ul>
&lt;h3 id="oreilly">
&lt;a class="heading-anchor-link" href="#oreilly">Oreilly&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="oreilly"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: eBooks&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Paid/Subscription&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: Rich and high-quality books&lt;/li>
&lt;/ul>
&lt;h3 id="medium">
&lt;a class="heading-anchor-link" href="#medium">Medium&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="medium"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Blogs&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Paid/Subscription&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: Relatively high quality, and no ads&lt;/li>
&lt;/ul>
&lt;h3 id="things">
&lt;a class="heading-anchor-link" href="#things">Things&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="things"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: GTD&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Paid/One-time purchase&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: None&lt;/li>
&lt;/ul>
&lt;h3 id="telegram">
&lt;a class="heading-anchor-link" href="#telegram">Telegram&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="telegram"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: IM&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Free&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: The best communication app experience so far, also great for watching shows&lt;/li>
&lt;/ul>
&lt;h3 id="chrome">
&lt;a class="heading-anchor-link" href="#chrome">Chrome&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="chrome"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Browser&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Free&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: The best browser with multi-end cloud synchronization&lt;/li>
&lt;/ul>
&lt;h3 id="1password">
&lt;a class="heading-anchor-link" href="#1password">1Password&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="1password"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Password Management&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Paid/Subscription&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: None&lt;/li>
&lt;/ul>
&lt;h3 id="surge">
&lt;a class="heading-anchor-link" href="#surge">Surge&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="surge"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Network Proxy&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Paid&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: Extremely worth buying&lt;/li>
&lt;/ul>
&lt;h3 id="shadowrocket">
&lt;a class="heading-anchor-link" href="#shadowrocket">ShadowRocket&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="shadowrocket"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Network Proxy&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Paid&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: I mainly use Surge daily, but ShadowRocket is also very good, and it is cheaper&lt;/li>
&lt;/ul>
&lt;h3 id="eudic">
&lt;a class="heading-anchor-link" href="#eudic">EuDic&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="eudic"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Word Query&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Free&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: Supports dictionary import&lt;/li>
&lt;/ul>
&lt;h3 id="evernote">
&lt;a class="heading-anchor-link" href="#evernote">Evernote&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="evernote"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Knowledge Management&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Paid/Subscription&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: None&lt;/li>
&lt;/ul>
&lt;h3 id="jd">
&lt;a class="heading-anchor-link" href="#jd">JD&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="jd"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: E-commerce Shopping&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Paid/Subscription&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: None&lt;/li>
&lt;/ul>
&lt;h3 id="smzdm">
&lt;a class="heading-anchor-link" href="#smzdm">SMZDM&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="smzdm"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: E-commerce Shopping&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Free&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: None&lt;/li>
&lt;/ul>
&lt;h3 id="amap">
&lt;a class="heading-anchor-link" href="#amap">Amap&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="amap"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Map Navigation&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Free&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: None&lt;/li>
&lt;/ul>
&lt;h3 id="boss">
&lt;a class="heading-anchor-link" href="#boss">Boss&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="boss"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Job Search&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Free&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: None&lt;/li>
&lt;/ul>
&lt;h3 id="ctrip">
&lt;a class="heading-anchor-link" href="#ctrip">Ctrip&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ctrip"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Travel&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Free&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: I love the &amp;ldquo;Travel of a lifetime&amp;rdquo; feature&lt;/li>
&lt;/ul>
&lt;h3 id="google-photos">
&lt;a class="heading-anchor-link" href="#google-photos">Google Photos&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="google-photos"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Function&lt;/strong>: Photos&lt;/li>
&lt;li>&lt;strong>Pricing&lt;/strong>: Free&lt;/li>
&lt;li>&lt;strong>Note&lt;/strong>: Hosts all photos with unlimited storage&lt;/li>
&lt;/ul>
&lt;h2 id="at-the-end">
&lt;a class="heading-anchor-link" href="#at-the-end">At the end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="at-the-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>There is no best, only better. What suits you is the best.&lt;/li>
&lt;/ul></description></item><item><title>Getting the ASUS RT-AC1900P</title><link>https://en.1991421.cn/2020/09/13/59614e79/</link><pubDate>Sun, 13 Sep 2020 21:39:41 +0800</pubDate><guid>https://en.1991421.cn/2020/09/13/59614e79/</guid><description>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-09-13-214054.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;blockquote>
&lt;p>I&amp;rsquo;ve been working remotely from my hometown lately, and the internet signal keeps dropping. Constant disconnects are beyond frustrating, so I finally decided to upgrade the home router.&lt;/p>
&lt;/blockquote>
&lt;h2 id="choosing-a-router">
&lt;a class="heading-anchor-link" href="#choosing-a-router">Choosing a Router&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="choosing-a-router"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I had previously tried Xiaomi and Huawei routers, but both brands suffer from stability issues—understandable given the low price. After researching and getting recommendations from friends, I landed on the &lt;code>ASUS RT-AC1900P&lt;/code>, the upgraded version of the RT-AC68U.&lt;/p>
&lt;p>Price: &lt;code>499 RMB&lt;/code>&lt;/p>
&lt;h3 id="selection-criteria">
&lt;a class="heading-anchor-link" href="#selection-criteria">Selection Criteria&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="selection-criteria"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>&lt;code>Stability&lt;/code>: ASUS routers generally have a solid reputation, and picking a popular model adds extra peace of mind.&lt;/li>
&lt;li>&lt;code>Signal boosting with AiMesh&lt;/code>: this model supports it, so if the house is too big I can add another unit. Our place is around 180 square meters, with the router in the living room. Some rooms are three walls away, which definitely weakens the signal.&lt;/li>
&lt;li>&lt;code>Flexibility&lt;/code>: for example, it supports flashing the Merlin firmware. &lt;a href="https://post.smzdm.com/p/616625/" target="_blank" rel="noopener">Reference&lt;/a>&lt;/li>
&lt;/ol>
&lt;h2 id="one-week-impressions">
&lt;a class="heading-anchor-link" href="#one-week-impressions">One-Week Impressions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="one-week-impressions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Once I made the decision, I placed the order immediately. I have to say, JD&amp;rsquo;s shopping experience is impressive. Even in a small county, I ordered in the evening and the router arrived the next morning. Nice.&lt;/p>
&lt;p>Here are my impressions after a week of use:&lt;/p>
&lt;ol>
&lt;li>It looks better in person—the build quality feels premium.&lt;/li>
&lt;li>The signal is stable.&lt;/li>
&lt;li>With the router in the living room, the farthest room has to go through two or three walls, which drops the signal to two bars and causes buffering on 1080p YouTube videos. Rooms with two walls in between still get three bars and stream smoothly.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>My family mostly uses Wi-Fi in the living room and doesn&amp;rsquo;t need a home office setup, so I haven&amp;rsquo;t added another unit for AiMesh yet. But the router supports it, so if we ever need better coverage I can just buy a second one—affordable and flexible.&lt;/li>
&lt;li>After this purchase, I think I&amp;rsquo;ll skip Xiaomi and Huawei routers going forward. Sometimes the specialized brands really are better.&lt;/li>
&lt;/ul></description></item><item><title>Java Log Management and Operations Analysis</title><link>https://en.1991421.cn/2020/09/06/java/</link><pubDate>Sun, 06 Sep 2020 16:51:56 +0800</pubDate><guid>https://en.1991421.cn/2020/09/06/java/</guid><description>&lt;blockquote>
&lt;p>After project deployment, whenever system interaction issues occur, QA and BA teams often need to consult developers. Developers first check the code, search for log keywords, then perform searches in Kibana. Due to the large volume of log records, various filtering operations are also required. Ultimately, solving the problem might only take 10 minutes, but identifying the target logs can take over 30 minutes. When issues recur, the same time-consuming process repeats.&lt;/p>
&lt;p>Looking calmly at this troubleshooting process when problems occur reveals that multiple steps can be standardized and automated, indicating there&amp;rsquo;s room for optimization.&lt;/p>
&lt;/blockquote>
&lt;h2 id="log-system-technology-stack">
&lt;a class="heading-anchor-link" href="#log-system-technology-stack">Log System Technology Stack&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="log-system-technology-stack"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Before optimization, let&amp;rsquo;s understand the current technology stack for logging in our project&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-09-06-164411.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ul>
&lt;li>logback &lt;code>Recording&lt;/code>&lt;/li>
&lt;li>logstash &lt;code>Collection&lt;/code>&lt;/li>
&lt;li>kibana &lt;code>Viewing&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="principles-for-log-recording">
&lt;a class="heading-anchor-link" href="#principles-for-log-recording">Principles for Log Recording&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="principles-for-log-recording"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The Alibaba Java Development Manual (Taishan Edition) is quite good and recommended reading. Of course, ultimately it should be adapted to local circumstances.&lt;/p>
&lt;p>Here are several principles I personally value more:&lt;/p>
&lt;ul>
&lt;li>Separate business logs from exception logs&lt;/li>
&lt;li>Use English to describe log error messages whenever possible. If error messages cannot be clearly described in English, use Chinese instead to avoid ambiguity.&lt;/li>
&lt;li>If exceptions are not handled, they should be thrown upward&lt;/li>
&lt;/ul>
&lt;h2 id="log-recording-in-java">
&lt;a class="heading-anchor-link" href="#log-recording-in-java">Log Recording in Java&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="log-recording-in-java"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;code>Class name&lt;/code>, &lt;code>Method name&lt;/code>, &lt;code>Line number&lt;/code>&lt;/li>
&lt;li>&lt;code>Log keywords&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>For example, the following log record:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="n">log&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">info&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;quoteId: {} response: {}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">quoteId&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">JsonConverter&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">serializeObject&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">quoteWithSaleRegDTO&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="log-configuration">
&lt;a class="heading-anchor-link" href="#log-configuration">Log Configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="log-configuration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;h4 id="console-configuration">Console Configuration&lt;/h4>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yml" data-lang="yml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">logging&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pattern&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">console&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;%p [%d{yyyy-MM-dd HH:mm:ss,SSS}] %c{3}:[%C{1}:%M:%L] - [%t][%file:%line] - %m%n&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="logstash-configuration">logstash Configuration&lt;/h4>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="n">logstashEncoder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">setIncludeCallerData&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Detailed configuration &lt;a href="https://github.com/logstash/logstash-logback-encoder" target="_blank" rel="noopener">click here&lt;/a>&lt;/p>
&lt;h3 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Log metadata in Kibana depends on logstash configuration, while logback configuration only handles console log printing - they are different&lt;/li>
&lt;li>Logs are also part of the code, similar to comments. As volume increases, maintenance costs also increase. So items like method names and line numbers are strongly correlated but also variable, so automate whenever possible and avoid manual writing.&lt;/li>
&lt;/ul>
&lt;h2 id="log-viewing-in-kibana">
&lt;a class="heading-anchor-link" href="#log-viewing-in-kibana">Log Viewing in Kibana&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="log-viewing-in-kibana"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Reconfiguring queries for specific business functions each time is actually very time-consuming. Kibana provides a save function, so a better approach is to store frequently used search conditions, while using labels to describe the conditions.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-09-06-163511.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-09-06-163603.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-09-06-164203.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-09-07-082413.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="notes-1">
&lt;a class="heading-anchor-link" href="#notes-1">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Use labels to describe conditions for easier understanding&lt;/li>
&lt;li>Log time ranges and auto-refresh are also important for quickly accessing logs from the problem occurrence period&lt;/li>
&lt;li>For different environments where we need quick synchronization and sharing of search configurations, import/export can solve this, avoiding the need to reconfigure each environment system&lt;/li>
&lt;li>Fields exposed by callerData like method and class can also be used for search filtering, but for new fields added to Kibana, you need to execute management =&amp;gt; index patterns =&amp;gt; Refresh field list first before they can be used for filtering&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Logs play a crucial role in troubleshooting and tracing various issues after a product goes live. Therefore, valuing logs involves one approach of structuring log information, such as the class names, method names, line numbers, and subjectively injected keyword variables mentioned above. Another approach is optimizing search efficiency using tools for log retrieval.&lt;/li>
&lt;li>Seeing some colleagues blindly writing logs, similar to how they approach comments, it&amp;rsquo;s important to know that both comments and logs are part of the code. Once written, they incur maintenance costs, so they should be moderate, appropriate, and scientific.&lt;/li>
&lt;/ul>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/watch?v=gQ1c1uILyKI&amp;amp;t=36s&amp;amp;ab_channel=edureka%21" target="_blank" rel="noopener">https://www.youtube.com/watch?v=gQ1c1uILyKI&amp;t=36s&amp;ab_channel=edureka%21&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/logstash/logstash-logback-encoder" target="_blank" rel="noopener">logstash-logback-encoder&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Concurrency, Parallelism, Processes, and Threads</title><link>https://en.1991421.cn/2020/08/17/concurrency-parallelism-process-thread/</link><pubDate>Mon, 17 Aug 2020 22:06:56 +0800</pubDate><guid>https://en.1991421.cn/2020/08/17/concurrency-parallelism-process-thread/</guid><description>&lt;blockquote>
&lt;p>Whether it&amp;rsquo;s Java or JavaScript, we encounter concurrency and parallelism issues in programming, which inevitably involve threads and processes. Let me organize these concepts here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="an-analogy-for-concurrency-and-parallelism">
&lt;a class="heading-anchor-link" href="#an-analogy-for-concurrency-and-parallelism">An Analogy for Concurrency and Parallelism&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="an-analogy-for-concurrency-and-parallelism"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I saw a vivid analogy on Zhihu:&lt;/p>
&lt;ul>
&lt;li>You&amp;rsquo;re eating dinner and the phone rings, but you wait until you finish eating before answering. This means you don&amp;rsquo;t support concurrency or parallelism.&lt;/li>
&lt;li>You&amp;rsquo;re eating dinner and the phone rings, so you stop eating, answer the phone, and then continue eating afterward. This means you support concurrency.&lt;/li>
&lt;li>You&amp;rsquo;re eating dinner and the phone rings, so you eat while talking on the phone. This means you support parallelism.&lt;/li>
&lt;/ul>
&lt;p>OK, you can see that the fundamental difference between concurrency and parallelism is &lt;code>simultaneity&lt;/code>.&lt;/p>
&lt;h2 id="threads-and-processes">
&lt;a class="heading-anchor-link" href="#threads-and-processes">Threads and Processes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="threads-and-processes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>A process is like a workshop in a factory. It represents a single task that the CPU can handle. At any given moment, the CPU is always running one process, while other processes are in a non-running state.&lt;/li>
&lt;li>In a workshop, there can be many workers who collaborate to complete a task. A thread is like a worker in the workshop. A process can include multiple threads.&lt;/li>
&lt;li>A CPU can only execute one process at a time, but a multi-core CPU can naturally execute multiple processes simultaneously.&lt;/li>
&lt;/ul>
&lt;h2 id="concurrency-and-parallelism-in-javascript">
&lt;a class="heading-anchor-link" href="#concurrency-and-parallelism-in-javascript">Concurrency and Parallelism in JavaScript&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="concurrency-and-parallelism-in-javascript"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Does concurrency exist in JavaScript?&lt;/p>
&lt;p>YES, JavaScript has a concurrency model based on an event loop. The event loop is responsible for executing code, collecting and processing events, and executing sub-tasks in the queue.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-08-17-213219.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Does parallelism exist in JavaScript?
NO, JavaScript is single-threaded and can only do one thing at a time. However, note that browsers are multi-process and support concurrent connections, so multiple connections can be active simultaneously at any given moment. For example, after initiating concurrent XHR requests, multiple connections might be processing simultaneously, or when loading JS resources - these situations represent parallelism.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="concurrency-and-parallelism-in-java">
&lt;a class="heading-anchor-link" href="#concurrency-and-parallelism-in-java">Concurrency and Parallelism in Java&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="concurrency-and-parallelism-in-java"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As mentioned above, the key to parallelism lies in simultaneity. For example, we know machines have multi-core CPUs, but when the JVM starts, it occupies one process, and threads share process resources. So would the multi-core CPU be wasted?&lt;/p>
&lt;p>NO&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-08-17-215705.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-08-17-220404.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>In Windows and Linux, the mapping relationship between Java threads and operating system threads is one-to-one. Therefore, threads can utilize multi-core CPUs.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I feel that simple problems seem to be pulled in different directions by various voices online. We still need to calm down, read some books, and think things through. Then everything becomes clear.&lt;/p></description></item><item><title>Escalation of Commitment</title><link>https://en.1991421.cn/2020/08/17/promise-upgrade/</link><pubDate>Mon, 17 Aug 2020 09:49:55 +0800</pubDate><guid>https://en.1991421.cn/2020/08/17/promise-upgrade/</guid><description>&lt;blockquote>
&lt;p>Recently, while reading &amp;ldquo;Thinking in Java&amp;rdquo; 4th Edition by Bruce Eckel, I encountered this term. Being unfamiliar with it, I looked it up on Wikipedia and couldn&amp;rsquo;t help but think about why the West is so powerful - they summarize and categorize the behavioral patterns and principles behind all phenomena. Combining this with my recent thoughts at work, I feel this concept has practical applications, so I&amp;rsquo;m marking it down here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-08-17-095843.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="concept">
&lt;a class="heading-anchor-link" href="#concept">Concept&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="concept"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;code>Escalation of commitment&lt;/code> is a &lt;code>behavioral pattern&lt;/code> that refers to when individuals or groups face increasingly negative outcomes, they tend to continue rationalizing existing decisions, actions, and investments rather than changing them.&lt;/p>
&lt;p>The essence of this behavioral pattern lies in the sunk cost fallacy, which economists and behavioral scientists use to describe how when people realize their previous accumulated investments (sunk costs) have been wasted, they make irrational choices because they feel the already invested and unrecoverable costs would be &amp;ldquo;wasted.&amp;rdquo; For example, when consumers find out movie tickets are non-refundable, many force themselves to watch a movie they don&amp;rsquo;t want to see because they&amp;rsquo;re afraid of wasting the ticket money.&lt;/p>
&lt;p>The above is excerpted from &lt;a href="https://zh.wikipedia.org/wiki/%E6%89%BF%E8%AB%BE%E5%8D%87%E7%B4%9A" target="_blank" rel="noopener">Wikipedia&lt;/a>&lt;/p>
&lt;h2 id="my-thoughts-at-work">
&lt;a class="heading-anchor-link" href="#my-thoughts-at-work">My Thoughts at Work&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-thoughts-at-work"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In software development, part of the work isn&amp;rsquo;t just simply adding code. Sometimes we face situations where the original design was not okay and the existing code has problems. As a developer, being greedy for the so-called current correctness and speed, continuing with the original design, thereby worsening problems and enlarging pitfalls for future developers - this is wrong. For the project, it&amp;rsquo;s a mistake; for yourself, you lose an opportunity for improvement. After all, if you can create your own design that&amp;rsquo;s better than the previous one, the benefits this choice brings you are greater than just continuing with the problematic original design.&lt;/p>
&lt;ul>
&lt;li>I remember discussing this issue with colleagues and concluded that &lt;code>developing and modifying programs requires being bold yet meticulous&lt;/code>.&lt;/li>
&lt;li>This doesn&amp;rsquo;t mean we should negate the past - we must have reverence for history and respect for predecessors. But at the same time, we should objectively evaluate the right and wrong of a design or piece of code, always consider the best solution, and ultimately make choices by combining various factors, rather than making excuses for ourselves. Both the process and results of this exploratory thinking are very important.&lt;/li>
&lt;li>Sometimes we often joke, &amp;ldquo;Look at this code of yours, it will be forever nailed to the pillar of shame in history.&amp;rdquo; This statement is a joke, but if it&amp;rsquo;s not a joke, its only purpose is to urge you to improve every day and always write the best program you can at the time.&lt;/li>
&lt;/ul></description></item><item><title>加入Medium Partner Program</title><link>https://en.1991421.cn/2020/08/12/medium-partner-program/</link><pubDate>Wed, 12 Aug 2020 06:04:36 +0800</pubDate><guid>https://en.1991421.cn/2020/08/12/medium-partner-program/</guid><description>&lt;h2 id="必备条件">
&lt;a class="heading-anchor-link" href="#%e5%bf%85%e5%a4%87%e6%9d%a1%e4%bb%b6">必备条件&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="必备条件"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Visa双币卡或PayPal等支付手段&lt;/li>
&lt;/ol>
&lt;h2 id="stripe账户注册">
&lt;a class="heading-anchor-link" href="#stripe%e8%b4%a6%e6%88%b7%e6%b3%a8%e5%86%8c">Stripe账户注册&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="stripe账户注册"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>大陆身份无法直接注册stripe账户，因此可以注册港区，当然前提是有港卡储蓄卡，这样提现方便。&lt;/p>
&lt;p>简单注册成功后，点击设置，选择&lt;code>Bank accounts and scheduling&lt;/code>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-08-12-061234.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>港区在添加账户时需要输入香港身份证，使用网上fake的信息进行输入，之后会收到邮件提醒不过审，这时选择提交护照来进行审查即可。即可以理解为整个信息都是真实。&lt;/p>
&lt;h2 id="mpp加入">
&lt;a class="heading-anchor-link" href="#mpp%e5%8a%a0%e5%85%a5">MPP加入&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mpp加入"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="medium会员订阅">
&lt;a class="heading-anchor-link" href="#medium%e4%bc%9a%e5%91%98%e8%ae%a2%e9%98%85">Medium会员订阅&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="medium会员订阅"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>订阅medium会员，否则无法加入MPP/挣钱&lt;/p>
&lt;p>5刀/月&lt;/p>
&lt;h3 id="连接stripe账户">
&lt;a class="heading-anchor-link" href="#%e8%bf%9e%e6%8e%a5stripe%e8%b4%a6%e6%88%b7">连接Stripe账户&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="连接stripe账户"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>如上Stripe账户注册OK后，这一步之需要点击跳转将会自动连接Stripe账户&lt;/p>
&lt;img src="https://static.1991421.cn/2020/2020-08-12-060548.jpeg" style="zoom:50%;" />
&lt;h3 id="填写taxpayer">
&lt;a class="heading-anchor-link" href="#%e5%a1%ab%e5%86%99taxpayer">填写Taxpayer&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="填写taxpayer"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>
&lt;p>按照&lt;code>真实信息填写&lt;/code>，比如大陆同学，选择w-8ben即可，注意所有地址都要填写真实，国家选择中国&lt;/p>
&lt;ul>
&lt;li>地址用英文填写，实测不需要太精确，因为有长度限制&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>审核需要3-5个工作日，注意查收邮件，如果时间过长一般是因为被拒绝了，具体可以邮件联系medium咨询&lt;/p>
&lt;p>&lt;a href="mailto:partnerprogram@medium.com">partnerprogram@medium.com&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;img src="https://static.1991421.cn/2024/2024-02-03-163159.jpeg" alt="https://static.1991421.cn/2024/2024-02-03-163159.jpeg" style="zoom:50%;" />
&lt;h3 id="更换绑定的stripe账户">
&lt;a class="heading-anchor-link" href="#%e6%9b%b4%e6%8d%a2%e7%bb%91%e5%ae%9a%e7%9a%84stripe%e8%b4%a6%e6%88%b7">更换绑定的Stripe账户?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="更换绑定的stripe账户"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>选择&lt;code>leave mpp&lt;/code>，重新加入mpp发现还是不行。&lt;/li>
&lt;li>这里我通过重新注册medium账号来解决&lt;/li>
&lt;/ul>
&lt;h2 id="发布文章">
&lt;a class="heading-anchor-link" href="#%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0">发布文章&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="发布文章"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>文章需要设置勾选&lt;code>Paywall your story&lt;/code>，效果即文章为会员只读，否则文章无法盈利。&lt;/li>
&lt;/ol>
&lt;h2 id="stripe收款提现">
&lt;a class="heading-anchor-link" href="#stripe%e6%94%b6%e6%ac%be%e6%8f%90%e7%8e%b0">Stripe收款/提现&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="stripe收款提现"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="添加银行账户">
&lt;a class="heading-anchor-link" href="#%e6%b7%bb%e5%8a%a0%e9%93%b6%e8%a1%8c%e8%b4%a6%e6%88%b7">添加银行账户&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="添加银行账户"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;img src="https://static.1991421.cn/2024/2024-03-16-090751.jpeg" alt="https://static.1991421.cn/2024/2024-03-16-090751.jpeg" style="zoom:50%;" />
&lt;ol>
&lt;li>姓名是拼音，有空格&lt;/li>
&lt;li>注意账号指的是港卡-港币账户的账号，长度为&lt;code>9位&lt;/code>，不包含银行编码/分行编码，即港币账号倒数9位&lt;/li>
&lt;li>银行/分行按照编码正确选择，该设置影响Routing number&lt;/li>
&lt;/ol>
&lt;p>如果账户填写不正确，则会出现提现失败。&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-03-13-205209.jpeg"
alt="https://static.1991421.cn/2024/2024-03-13-205209.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Stripe中查看具体报错信息如下&lt;/p>
&lt;blockquote>
&lt;p>The bank account details on file are probably incorrect. The routing number seems correct, but the account number is invalid.&lt;/p>
&lt;/blockquote>
&lt;h3 id="银行账号例子">
&lt;a class="heading-anchor-link" href="#%e9%93%b6%e8%a1%8c%e8%b4%a6%e5%8f%b7%e4%be%8b%e5%ad%90">银行账号例子&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="银行账号例子"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>*&lt;strong>EXAMPLE*&lt;/strong>
Beneficiary Bank: HSBC Hong Kong
Beneficiary Bank Address: 1 Queen&amp;rsquo;s Road Central
SWIFT code: HSBCHKHHHKH
Account number: 510-456789-001
Company Name: AUXIO COMPANY LIMITED&lt;/p>
&lt;p>*&lt;strong>Note&lt;/strong>
Account number: 510-456789-001
香港银行账号通常采用这种格式，因此用户通常会在 Stripe 的账号字段中插入所有这些信息。这是不正确的。
*&lt;strong>上述信息拆开后&lt;/strong>
分行编号: 510
账号: 456789001 &lt;em>(去除 &amp;ldquo;510&amp;rdquo;!)&lt;/em>&lt;/p>
&lt;h3 id="提现">
&lt;a class="heading-anchor-link" href="#%e6%8f%90%e7%8e%b0">提现&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="提现"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>按照加入日期，Medium会将收益每个月会打款到Stripe，Stripe也会自动将其提现到银行卡。具体执行日期可以在Medium页面底部查看。https://medium.com/me/partner/dashboard&lt;/p>
&lt;p>比如我的执行日期如下。&lt;/p>
&lt;blockquote>
&lt;p>We’ll typically send February payments by Mar 8. Payments may take 5-7 business days to appear in your bank account. Earnings are non-binding. Based on your taxpayer information, payments will be subject to international tax withholding of 10%.&lt;/p>
&lt;/blockquote>
&lt;p>具体Stripe提现到银行时间，以我的情况来看都是北京时间的下午。&lt;/p>
&lt;h2 id="写在最后">
&lt;a class="heading-anchor-link" href="#%e5%86%99%e5%9c%a8%e6%9c%80%e5%90%8e">写在最后&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="写在最后"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>整个过程还是有些麻烦的，s但折腾一次收获还是很大的。&lt;/p>
&lt;ol>
&lt;li>Medium加入了MPP，对于像我这样喜欢写作的人，有个良性的收益平台挺好，当然具体能否盈利看接下来的持续写作了。&lt;/li>
&lt;li>Stripe国外非常流行，比如GitHub Sponsor也是Stripe，解决后，同类需求都可以走stripe再到港卡。&lt;/li>
&lt;/ol>
&lt;h2 id="参考资料">
&lt;a class="heading-anchor-link" href="#%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99">参考资料&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="参考资料"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://zhuanlan.zhihu.com/p/98765328" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/98765328&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://52tw.me/353.html" target="_blank" rel="noopener">https://52tw.me/353.html&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.ggfbshop.com/index.php/2021/11/02/%E5%85%B3%E4%BA%8Estripe/" target="_blank" rel="noopener">关于Stripe&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://help.medium.com/hc/en-us/articles/115011928308-Make-a-story-eligible-to-earn-money" target="_blank" rel="noopener">Make a story eligible to earn money&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/watch?v=Dl53poAkbZo&amp;amp;ab_channel=%E6%95%B0%E5%AD%97%E7%89%A7%E6%B0%91LC" target="_blank" rel="noopener">Stripe 注册教程、国内注册 Stripe 香港帐号教程-YouTube&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Keep Translating</title><link>https://en.1991421.cn/2020/07/19/persistence-in-translation/</link><pubDate>Sun, 19 Jul 2020 12:35:32 +0800</pubDate><guid>https://en.1991421.cn/2020/07/19/persistence-in-translation/</guid><description>&lt;blockquote>
&lt;p>I recently discovered Crowdin and realized I could use it to translate technical docs — super convenient. I set myself a goal of contributing ~30 minutes daily. I’m translating the Ionic framework (hybrid mobile; can target desktop too).&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-07-19-124014.jpeg"
alt="Crowdin dashboard"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>After five consecutive days, a few observations stood out.&lt;/p>
&lt;h2 id="takeaways">
&lt;a class="heading-anchor-link" href="#takeaways">Takeaways&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="takeaways"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Translation quality depends on subject-matter knowledge and language fundamentals.&lt;/strong> I’ve shipped apps with Ionic v1–v4, and I’m used to reading English docs, so most strings are effortless—except when I hit commands I’ve never run, such as publishing to the App Store. The more you know the tech, the smoother the translation. Ideally translate topics you already use, or learn them as you go.&lt;/li>
&lt;li>&lt;strong>Progress accumulates slowly.&lt;/strong> Back in 2016, when Angular rewrote everything, Chinese docs were scarce. I forced myself to read English sources. From there it snowballed: reading official docs → translating Webpack/Angular/Bootstrap → switching OS/app UIs to English → regularly browsing Twitter, Medium, O’Reilly, even framework source. The change wasn’t overnight, but now I can read technical material without fear—though vocabulary and grammar still need work.&lt;/li>
&lt;/ol>
&lt;h2 id="keep-translating">
&lt;a class="heading-anchor-link" href="#keep-translating">Keep Translating&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="keep-translating"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Crowdin turned out to be the missing channel. Lots of engineers want to give back; they just lacked an efficient path. Crowdin makes contributing painless.&lt;/li>
&lt;li>As engineers we shouldn’t only consume—we can build tools, translate docs, and share knowledge. Contribution sharpens skills and might open unexpected doors. If it’s the right thing, it’s worth doing.&lt;/li>
&lt;/ul>
&lt;h2 id="closing-thoughts">
&lt;a class="heading-anchor-link" href="#closing-thoughts">Closing Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="closing-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Just a quick journal entry about the past few days. Onward and upward.&lt;/p></description></item><item><title>KSA Model</title><link>https://en.1991421.cn/2020/06/22/ksa-model/</link><pubDate>Mon, 22 Jun 2020 23:24:22 +0800</pubDate><guid>https://en.1991421.cn/2020/06/22/ksa-model/</guid><description>&lt;p>I recently signed up for a GeekTime course on English for internet professionals. At the beginning, the instructor introduced the KSA model. It left a strong impression, so I wrote down my thoughts.&lt;/p>
&lt;blockquote>
&lt;p>KSA (Knowledge, Skills and Abilities framework) is a model of knowledge, skills, and abilities. It explains the difference and relationship between knowledge and skills.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-06-22-232852.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>The instructor&amp;rsquo;s point was that for foreign languages, we should treat them as skills rather than knowledge. That woke me up. In programming, APIs and methods are just knowledge; what we should invest time in learning and mastering is skill. One way to learn skills is imitation and deliberate practice.&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://cn.careerlu.com/66964-understanding-knowledge-skills-and-abilities-ksa-2275329-76" target="_blank" rel="noopener">KSA: Understanding the Knowledge, Skills and Abilities Model 2020 - Management - Leadership&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Bought AirPods (2nd Gen)</title><link>https://en.1991421.cn/2020/06/16/airpods2/</link><pubDate>Tue, 16 Jun 2020 22:40:35 +0800</pubDate><guid>https://en.1991421.cn/2020/06/16/airpods2/</guid><description>&lt;blockquote>
&lt;p>2018.1我以没有任何优惠的价格JD入手了AirPods1代，真印证了一句话，早买早享受，应该说这是一件非常值得买的利器，我曾后悔买晚了。2020年开始，电池极度不耐操，于是最近入手了新款的AirPods，价格&lt;code>997CNY&lt;/code>。Airpods1代寿命&lt;code>2.5年&lt;/code>，结束使用。&lt;/p>
&lt;p>所谓踏雪又痕，这里也就简单记录下，我是如何看待AirPods和选择的。兴许还能帮到些朋友。&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-06-16-231552.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="are-airpods-worth-it">
&lt;a class="heading-anchor-link" href="#are-airpods-worth-it">Are AirPods worth it?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="are-airpods-worth-it"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>额，大废话，因人而异，于我而言，极其值得买，我有以下几个场景需要&lt;/p>
&lt;ol>
&lt;li>通勤路上，健身房等听歌&lt;/li>
&lt;li>电话，没有那面条般的线条，你说有多爽，双击挂断，爽歪歪&lt;/li>
&lt;li>当我听朋友说他们不怎么用Siri时，我吃了个惊，我谈不上重度用户，但是比如电话爸妈，我真的不想点击电话，点击人名等操作，直接Siri唤起-电话老爸-不好吗？&lt;/li>
&lt;/ol>
&lt;p>除此之外实际上有时AirPods一键切换到Mac，进行电话会议等功能也都是很高效。&lt;/p>
&lt;p>对于要不要买AirPods，如果不是苹果生态用户，我觉得真的没必要买，apple的产品从来都不是独立一款存在的，围绕着硬件软件生态体验才是完整完美。所以假如你不是苹果生态用户，你能用，但你用不爽。&lt;/p>
&lt;h2 id="gen-2-vs-gen-1">
&lt;a class="heading-anchor-link" href="#gen-2-vs-gen-1">Gen 2 vs. Gen 1&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="gen-2-vs-gen-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>2代与1代相比，主要是以下几个点&lt;/p>
&lt;h3 id="siri">
&lt;a class="heading-anchor-link" href="#siri">Siri&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="siri"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>记得2代才出的时候，实际上我是很兴奋的，因为1代我相对不满意的最大的槽点就是Siri，因为它需要双击唤起，假如力度大了，你都会把耳机敲掉。而现在呢，它可以一直待机，语音唤起，并且续航没有因此减少，你说爽不爽。&lt;/p>
&lt;h3 id="wireless-charging">
&lt;a class="heading-anchor-link" href="#wireless-charging">Wireless charging&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="wireless-charging"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>so,买新不买旧。但Apple不地道的是，充电指示灯在有线版充电盒和无线版充电盒的位置还不同，这点一肚子的坏水啊。不过这个并不重要，无线充电要不重要，于是我选择了有线充电盒版的。&lt;/p>
&lt;h3 id="pro">
&lt;a class="heading-anchor-link" href="#pro">Pro&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pro"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>这次Apple还出了降噪版的，但一方面是我有了bose700,所以这个刚需不大，另一方面是入耳式的耳机本身就对耳朵的损伤大于耳罩式，so，综上我没考虑Pro.&lt;/p>
&lt;p>但假如想兼顾降噪，确实可以考虑，毕竟买两个成本更高。&lt;/p>
&lt;h2 id="battery-lifespan">
&lt;a class="heading-anchor-link" href="#battery-lifespan">Battery lifespan&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="battery-lifespan"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>如上所说，我是&lt;code>2018.1&lt;/code>入手的1代，&lt;code>2020.5&lt;/code>时，它充满一次电，半个小时的会议后，一个耳机的电量已经只剩下了17%，另一个多一点。在这2年半的时间里，我的使用频次是很高的，当然每天倒不是无时无刻的使用，毕竟我不是播音主持专业的。&lt;/p>
&lt;p>结论：&lt;code>偏高频使用的话，AirPods的寿命为2年，盒子其实还好，主要问题是耳机本身，2年后就开始明显不行。&lt;/code>&lt;/p>
&lt;h2 id="resale">
&lt;a class="heading-anchor-link" href="#resale">Resale&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="resale"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>我曾考虑过闲鱼，但是使用只有几个月的也就卖500多吧，强大的PDD百亿补贴的2代新品也就卖800多，所以我这种2年半的二手旧货是很难卖出价的，并且&lt;code>闲鱼的一部分买家永远是一种1元想买宇宙的心态&lt;/code>，还啰嗦，极其浪费我的时间，so，这条路子不行。&lt;/p>
&lt;p>最终我选择了京东官方的回收渠道，卖了&lt;code>228.6&lt;/code>，整个流程是&lt;code>京东官方快递拿货=&amp;gt;验货=&amp;gt;估价=》手机确认价格后，直接打钱到你指定的账户&lt;/code>。极其痛快，因此个人觉得还可以。&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-06-16-230523.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>18年入手时的价格是&lt;code>1248&lt;/code>,相当于2年半花费了&lt;code>1K&lt;/code>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>在购买AirPods和出手旧AirPods的整个过程中，其实我最大的收获是更认识了京东回收这块的价值，它完全可以互补闲鱼的不足，作为我们日常出手闲置，回血的一个手段。&lt;/p></description></item><item><title>Learn to Ask Better Questions</title><link>https://en.1991421.cn/2020/06/12/learn-to-ask-questions/</link><pubDate>Fri, 12 Jun 2020 09:45:47 +0800</pubDate><guid>https://en.1991421.cn/2020/06/12/learn-to-ask-questions/</guid><description>&lt;p>While working with the Alfred community, I confused an evangelist so badly that he told me, “This is an X-Y problem.” That’s when I first learned the term (&lt;a href="https://coolshell.cn/articles/10804.html" target="_blank" rel="noopener">link&lt;/a>).&lt;/p>
&lt;p>Before asking anyone, we should double-check: am I describing the real problem? Can someone else understand it? Otherwise we waste both their time and ours.&lt;/p>
&lt;p>I’ve been in the industry six years, and asking questions is still a skill. Age doesn’t guarantee clarity. Kids can say “I want ice cream” directly. Adults ramble and leave listeners puzzled.&lt;/p></description></item><item><title>Switching Blog Search to Algolia</title><link>https://en.1991421.cn/2020/05/30/algolia/</link><pubDate>Sat, 30 May 2020 22:20:57 +0800</pubDate><guid>https://en.1991421.cn/2020/05/30/algolia/</guid><description>&lt;blockquote>
&lt;p>My personal blog was previously using Swiftype for search, but it has a trial period and started showing a 402 error after expiration. The local search experience was very poor, so I switched to Algolia. I found that there are different opinions online about configuring this service, and I encountered some pitfalls. I&amp;rsquo;m marking it down briefly here.&lt;/p>
&lt;/blockquote>
&lt;h2 id="current-blog-theme-version">
&lt;a class="heading-anchor-link" href="#current-blog-theme-version">Current Blog Theme Version&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-blog-theme-version"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>hexo - v3.9.0&lt;/li>
&lt;li>hexo-theme-next - v7.2.0&lt;/li>
&lt;/ul>
&lt;p>Note: Configuration may vary with different versions.&lt;/p>
&lt;h2 id="algolia-site-service-registration">
&lt;a class="heading-anchor-link" href="#algolia-site-service-registration">Algolia Site Service Registration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="algolia-site-service-registration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Log in to the official website, register an account, and create an index.&lt;/li>
&lt;li>Create an API in API Keys &amp;gt; All API Keys, ensuring it has permissions to search, add, and delete indexes.&lt;/li>
&lt;/ul>
&lt;p>The &lt;code>search, admin API Key&lt;/code> and index name will be used in the blog configuration.&lt;/p>
&lt;h2 id="theme-configuration-file">
&lt;a class="heading-anchor-link" href="#theme-configuration-file">Theme Configuration File&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="theme-configuration-file"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Enable the Algolia service.&lt;/p>
&lt;h2 id="blog-main-configuration-file">
&lt;a class="heading-anchor-link" href="#blog-main-configuration-file">Blog Main Configuration File&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="blog-main-configuration-file"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yml" data-lang="yml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">algolia&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">appId&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">applicationID&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">apiKey&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">adminApiKey&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">chunkSize&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">5000&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">indexName&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">my_blog&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">fields&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">content:strip:truncate,0,500&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">excerpt:strip&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">gallery&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">permalink&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">photos&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">slug&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">tags&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">title&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>No need to install &lt;code>npm install --save hexo-algolia&lt;/code> as mentioned on the Next official website; I recommend &lt;code>npm install hexo-algoliasearch --save&lt;/code> instead. Skip this if already installed.&lt;/li>
&lt;li>appId and applicationID have the same value. The reason for having both is that the configuration items required for site content indexing are inconsistent with those in the theme template, possibly due to version mismatches. I don&amp;rsquo;t want to check the details; it&amp;rsquo;s not important.&lt;/li>
&lt;/ul>
&lt;h2 id="index-generation">
&lt;a class="heading-anchor-link" href="#index-generation">Index Generation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="index-generation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ &lt;span class="nb">export&lt;/span> &lt;span class="nv">HEXO_ALGOLIA_INDEXING_KEY&lt;/span>&lt;span class="o">=&lt;/span>xxxx
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ hexo algolia
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Note: The default shell on Windows does not support &lt;code>export&lt;/code>; you can execute this in Git Bash.&lt;/p>
&lt;p>After the above configuration, the search service is ready to use.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I have now tried all the search services supported by the NexT theme: local search, Swiftype, and Algolia. If Algolia also fails, I will have to build a custom search service. Let&amp;rsquo;s wait for that need to arise.&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="http://theme-next.iissnan.com/third-party-services.html#wei-sousuo" target="_blank" rel="noopener">http://theme-next.iissnan.com/third-party-services.html#wei-sousuo&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Emoji Explained (Simple Guide)</title><link>https://en.1991421.cn/2020/05/09/emoji/</link><pubDate>Sat, 09 May 2020 16:23:24 +0800</pubDate><guid>https://en.1991421.cn/2020/05/09/emoji/</guid><description>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-05-07-225828.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;blockquote>
&lt;p>I saw a quiz in a chat group: what is &lt;code>'✈️'.length&lt;/code>? That stumped me, so I dug in and took notes.&lt;/p>
&lt;/blockquote>
&lt;h2 id="what-is-emoji">
&lt;a class="heading-anchor-link" href="#what-is-emoji">What is emoji?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-is-emoji"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>emoji（英语：emoji，日语：絵文字／えもじ emoji），是使用在网页和聊天中的形意符号&lt;/p>
&lt;/blockquote>
&lt;ul>
&lt;li>Emojis are characters, not images.&lt;/li>
&lt;li>The same emoji looks different on Twitter/iOS/Windows because code points are standard, but rendering depends on platform fonts.&lt;/li>
&lt;/ul>
&lt;h2 id="character-encoding">
&lt;a class="heading-anchor-link" href="#character-encoding">Character encoding&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="character-encoding"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>在搞明白&lt;code>'✈️'.length&lt;/code>之前，先补下编码知识&lt;/p>
&lt;p>我们常说的编码有这些。ASCII(国际编码)，Unicode（国际符号集）,UTF8(国际编码)，GB2312(国标编码),ISO-8859-1(国际编码)&lt;/p>
&lt;p>We used to run into encoding issues (archives, web pages, uploads/downloads) more often; less so today as standards converged.&lt;/p>
&lt;ul>
&lt;li>ASCII只考虑了英文字符&lt;/li>
&lt;li>Unicode考虑了世界上各种字符，符号，规定了符号的二进制代码&lt;/li>
&lt;li>Unicode只是一个符号集，它只规定了符号的二进制代码，却没有规定这个二进制代码 应该如何存储&lt;/li>
&lt;li>&lt;code>UTF-8 is one implementation of Unicode&lt;/code>, a variable‑length encoding using 1–4 bytes per code point.&lt;/li>
&lt;li>Unicode 编码范围是从 U+0000 到 U+10FFFF，每一个编码（也称之为码位 code point）表示一个 Unicode 字符；而这么多码位有划分成 17 个平面：
第一个平面(U+0000 ~ U+FFFF): 基本平面(Basic Multilingual Plane - BMP)
其他 16 个平面(U+100000 ~ U+10FFFF): 补充平面(Supplementary Planes)&lt;/li>
&lt;li>GB2312是&lt;code>国标&lt;/code>，但是今天几乎所有站点都是UTF8，GB2312已经被淘汰。&lt;/li>
&lt;li>ISO-8859-1 不是Unicode字符集，原因是并不对所有符号编码，只是一部分，今天也很少见该编码&lt;/li>
&lt;li>JavaScript engines internally use UCS‑2/UTF‑16.&lt;/li>
&lt;li>Java默认编码方式是UTF-16&lt;/li>
&lt;/ul>
&lt;p>下图可以简单的看出几种编码的区别，以后应该主要是UTF了&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-05-09-151739.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="emoji-length">
&lt;a class="heading-anchor-link" href="#emoji-length">Emoji “length”&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="emoji-length"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>编码知道后，再一开始的长度疑问&lt;/p>
&lt;ul>
&lt;li>In JS, &lt;code>'123'.length===3&lt;/code> counts code units, not bytes.&lt;/li>
&lt;li>Code points, bytes, and JS string length are not equivalent.&lt;/li>
&lt;li>Different emojis correspond to different code unit lengths.&lt;/li>
&lt;/ul>
&lt;h2 id="unicode-and-emoji">
&lt;a class="heading-anchor-link" href="#unicode-and-emoji">Unicode and emoji&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="unicode-and-emoji"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>BMP emojis may be 1 code unit.&lt;/li>
&lt;li>BMP multi‑code‑point sequences may be 2 code units.&lt;/li>
&lt;li>Supplementary plane single code points are typically 2 code units in UTF‑16.&lt;/li>
&lt;li>Multi‑code‑point sequences vary.&lt;/li>
&lt;/ul>
&lt;h3 id="举个例子">
&lt;a class="heading-anchor-link" href="#%e4%b8%be%e4%b8%aa%e4%be%8b%e5%ad%90">举个例子&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="举个例子"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 各个表情字符个数
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;⛷&amp;#39;&lt;/span>&lt;span class="p">.&lt;/span> &lt;span class="nx">length&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// 1
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;😂&amp;#39;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// 2
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;1️⃣&amp;#39;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// 3
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;👨‍👨‍👦&amp;#39;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// 8
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;👨‍👩‍👧‍👦&amp;#39;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// 11
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="encodings-youll-see">
&lt;a class="heading-anchor-link" href="#encodings-youll-see">Encodings you’ll see&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="encodings-youll-see"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>System locale: run &lt;code>locale&lt;/code> in a terminal.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>搞开发的同学会看到IDE，各个程序文件都有文件编码，DB也有database编码&lt;/p>
&lt;/li>
&lt;li>
&lt;p>浏览器浏览网页HTML，CSS，JS也都有对应的编码&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Terminal text/emoji relies on encoding and fonts. If you see tofu/garbage, your font may lack glyphs — switch fonts.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-05-09-153855.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Even understanding encodings and emoji, it’s still nontrivial to predict code unit length at a glance. 😭&lt;/p>
&lt;h2 id="参考文档">
&lt;a class="heading-anchor-link" href="#%e5%8f%82%e8%80%83%e6%96%87%e6%a1%a3">参考文档&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="参考文档"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.ruanyifeng.com/blog/2017/04/emoji.html" target="_blank" rel="noopener">Emoji 简介&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html" target="_blank" rel="noopener">字符编码笔记：ASCII，Unicode 和 UTF-8&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://zh.wikipedia.org/wiki/GB_2312" target="_blank" rel="noopener">GB2312&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/" target="_blank" rel="noopener">The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://apps.timwhitlock.info/emoji/tables/unicode#block-6c-other-additional-symbols" target="_blank" rel="noopener">Emoji Unicode Tables&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.alloyteam.com/2016/12/javascript-has-a-unicode-sinkhole/" target="_blank" rel="noopener">Javascript 有个 Unicode 的天坑&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://objcer.com/2017/07/20/explore-emoji-length/" target="_blank" rel="noopener">探究 emoji 字符长度&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://zh.wikipedia.org/wiki/%E7%B9%AA%E6%96%87%E5%AD%97" target="_blank" rel="noopener">emoji WIKI&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.ruanyifeng.com/blog/2008/05/growth_of_utf-8_on_the_web.html" target="_blank" rel="noopener">utf-8编码已经成为主流&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://epingwang.me/2017/06/29/2017-06-29-%E6%8E%A2%E7%B4%A2iOS%E4%B8%ADEmoji%E8%A1%A8%E6%83%85%E7%9A%84%E7%BC%96%E7%A0%81%E4%B8%8E%E8%A7%A3%E6%9E%90/" target="_blank" rel="noopener">探索iOS中Emoji表情的编码与解析&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://mathiasbynens.be/notes/javascript-encoding" target="_blank" rel="noopener">JavaScript’s internal character encoding: UCS-2 or UTF-16?&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Keyboards Explained (Simple Guide)</title><link>https://en.1991421.cn/2020/05/05/keyboard-intro/</link><pubDate>Tue, 05 May 2020 23:20:59 +0800</pubDate><guid>https://en.1991421.cn/2020/05/05/keyboard-intro/</guid><description>&lt;blockquote>
&lt;p>Recently, while messing with Alfred&amp;rsquo;s hotkey bindings, I learned a term called &amp;ldquo;modifier keys&amp;rdquo; and looked it up to find out what keys they are. This made me realize that I don&amp;rsquo;t have a systematic understanding of basic keyboard layout terminology, so I searched and checked, and I&amp;rsquo;m marking it down here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-05-05-232932.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="modifier-keys">
&lt;a class="heading-anchor-link" href="#modifier-keys">Modifier keys&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="modifier-keys"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Modifier keys are also called combination keys; these keys are used in combination with other keys to serve different functions.&lt;/p>
&lt;ul>
&lt;li>⇧&lt;/li>
&lt;li>⌃&lt;/li>
&lt;li>⌥ Alt&lt;/li>
&lt;li>⌘ Windows&lt;/li>
&lt;li>&lt;del>Fn&lt;/del>&lt;/li>
&lt;/ul>
&lt;p>&lt;em>Wikipedia records Fn as one, but I personally don&amp;rsquo;t think it counts in today&amp;rsquo;s systems. Fn is more commonly used alone or in combination with other keys.&lt;/em>&lt;/p>
&lt;h2 id="keyboard-zones">
&lt;a class="heading-anchor-link" href="#keyboard-zones">Keyboard zones&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="keyboard-zones"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I usually use the keyboard without thinking, but let&amp;rsquo;s look at the system structure of ⌨️:&lt;/p>
&lt;ul>
&lt;li>Typing area
&lt;ol>
&lt;li>Numeric keys&lt;/li>
&lt;li>Alphabet keys&lt;/li>
&lt;li>Shift keys (shift)&lt;/li>
&lt;li>Symbol keys&lt;/li>
&lt;li>Space bar&lt;/li>
&lt;li>Backspace key&lt;/li>
&lt;li>Caps lock key&lt;/li>
&lt;li>Enter key (line feed key)&lt;/li>
&lt;li>Control keys (ctrl)&lt;/li>
&lt;li>Alt keys (⌥ Alt)&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Function key area
&lt;ul>
&lt;li>The commonly known Fn key area&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Numeric keypad
&lt;ol>
&lt;li>Num lock key&lt;/li>
&lt;li>Insert key&lt;/li>
&lt;li>Delete key&lt;/li>
&lt;li>Enter key (line feed key)&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Editing key area
&lt;ol>
&lt;li>Arrow keys&lt;/li>
&lt;li>Insert key&lt;/li>
&lt;li>Delete key&lt;/li>
&lt;li>Home key&lt;/li>
&lt;li>End key&lt;/li>
&lt;li>Page up key&lt;/li>
&lt;li>Page down key&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ul>
&lt;h3 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Modifier keys belong to the &lt;code>typing area&lt;/code>&lt;/li>
&lt;li>The main differences between 67-key, 87-key, and 104-key keyboards on the market are the removal of Fn function keys and numeric keypads.&lt;/li>
&lt;/ul>
&lt;h2 id="my-keyboard">
&lt;a class="heading-anchor-link" href="#my-keyboard">My keyboard&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-keyboard"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Das Keyboard, 87 keys, red switches, no separate numeric keypad, simple and great&amp;hellip;&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-05-05-235739.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Don&amp;rsquo;t hesitate—you deserve it!&lt;/p>
&lt;h2 id="karabiner">
&lt;a class="heading-anchor-link" href="#karabiner">Karabiner&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="karabiner"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I recommend a keyboard customization tool that includes two parts:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-05-06-131823.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Karabiner-Elements&lt;/p>
&lt;p>Allows you to customize keys based on your keyboard.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Karabiner-EventViewer&lt;/p>
&lt;p>Views key code, app, and other information.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Download &lt;a href="https://github.com/tekezo/Karabiner" target="_blank" rel="noopener">here&lt;/a>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Understanding the basic layout and key names of the keyboard has two benefits for me:&lt;/p>
&lt;ol>
&lt;li>It avoids obstacles in communication and information querying. For example, you now know what combination keys are.&lt;/li>
&lt;li>When using or developing software, you&amp;rsquo;ll have a better idea of how to design key bindings. For instance, you definitely wouldn&amp;rsquo;t design a feature like double-clicking &amp;ldquo;aa&amp;rdquo; to trigger an action because letter keys are in the typing area and used for high-frequency daily operations; their behavior shouldn&amp;rsquo;t be easily changed. However, using them in combination with modifier keys is very reasonable.&lt;/li>
&lt;/ol>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Modifier_key" target="_blank" rel="noopener">Modifier Key&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://zh.wikipedia.org/wiki/%E7%94%B5%E8%84%91%E9%94%AE%E7%9B%98" target="_blank" rel="noopener">Computer Keyboard&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>关于PayPal的使用</title><link>https://en.1991421.cn/2020/04/30/paypal/</link><pubDate>Thu, 30 Apr 2020 20:49:54 +0800</pubDate><guid>https://en.1991421.cn/2020/04/30/paypal/</guid><description>&lt;blockquote>
&lt;p>国内我们常用的第三方支付是微信和支付宝，而国外比较流行的是PayPal.&lt;/p>
&lt;p>为了方便国外支付，所以注册了港区PayPal。这里简单总结下。&lt;/p>
&lt;/blockquote>
&lt;h2 id="paypal注册">
&lt;a class="heading-anchor-link" href="#paypal%e6%b3%a8%e5%86%8c">PayPal注册&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="paypal注册"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>招商Visa信用卡&lt;/p>
&lt;ul>
&lt;li>大多数服务是不支持银联的，所以Visa卡很重要&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-30-210557.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>因为是港区，可以走真实地址和86手机号&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="paypal提现">
&lt;a class="heading-anchor-link" href="#paypal%e6%8f%90%e7%8e%b0">PayPal提现?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="paypal提现"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>因为个人有时候有些小钱，是在PayPal余额，曾尝试提现到国内银行的储值卡。但经过一番调查发现麻烦的要死，所以这个还是别想了。&lt;/p>
&lt;ol>
&lt;li>&lt;code>可以提现&lt;/code>，手段网上有，&lt;a href="https://zhuanlan.zhihu.com/p/48985278" target="_blank" rel="noopener">戳这里&lt;/a>&lt;/li>
&lt;li>提现有高额的手续费，如果很小的金额，像我这样的，还是算了。&lt;/li>
&lt;/ol>
&lt;h2 id="paypal余额作为首选支付手段">
&lt;a class="heading-anchor-link" href="#paypal%e4%bd%99%e9%a2%9d%e4%bd%9c%e4%b8%ba%e9%a6%96%e9%80%89%e6%94%af%e4%bb%98%e6%89%8b%e6%ae%b5">PayPal余额作为首选支付手段&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="paypal余额作为首选支付手段"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>这个需要&lt;code>设定下支付方式优先级&lt;/code>，与支付宝类似&lt;/li>
&lt;li>PayPal用来支付Vultr等还是挺方便的&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-30-210428.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="不建议美区paypal注册">
&lt;a class="heading-anchor-link" href="#%e4%b8%8d%e5%bb%ba%e8%ae%ae%e7%be%8e%e5%8c%bapaypal%e6%b3%a8%e5%86%8c">不建议美区PayPal注册&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="不建议美区paypal注册"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>没有美国真实身份信息，不建议申请美区Paypal了，美区Paypal需身份信息，如果用假的，当前的审核政策是无法通过的，因为需要上传身份信息，驾照信息等，最终还是会被锁号，无法正常交易，比如收钱。&lt;/li>
&lt;li>美区AppleID支付手段，只能在官网购买Gift Card，然后在商店登陆，选择Redeem Code&lt;/li>
&lt;/ul>
&lt;h2 id="写在最后">
&lt;a class="heading-anchor-link" href="#%e5%86%99%e5%9c%a8%e6%9c%80%e5%90%8e">写在最后&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="写在最后"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>搞定PayPal，再加Visa卡，至少支付手段上不再受限&lt;/li>
&lt;li>随着国外的站点陆续都支持了微信，支付宝，似乎PayPal不那么重要了，但还是建议注册一个&lt;/li>
&lt;/ul></description></item><item><title>WebSocket Reading Notes</title><link>https://en.1991421.cn/2020/04/19/websocket/</link><pubDate>Sun, 19 Apr 2020 16:31:02 +0800</pubDate><guid>https://en.1991421.cn/2020/04/19/websocket/</guid><description>&lt;blockquote>
&lt;p>I recently used WebSocket in a project but didn&amp;rsquo;t know much about it. I spent some time reading &lt;a href="https://www.amazon.cn/dp/B015D78JVQ/ref=sr_1_4?keywords=websocket&amp;amp;qid=1587293374&amp;amp;sr=8-4" target="_blank" rel="noopener">&amp;ldquo;WebSocket&amp;rdquo;&lt;/a>. Here are some takeaways.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-19-194807.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="the-mission-of-websocket">
&lt;a class="heading-anchor-link" href="#the-mission-of-websocket">The mission of WebSocket&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-mission-of-websocket"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>New technologies solve specific problems - Promises solve callback hell; XHR enables async requests. WebSocket arrived with HTML5 to provide full-duplex communication between the web and backend. Before WS, we relied on polling, and only the client could initiate requests.&lt;/p>
&lt;p>With WebSocket, both sides can push messages to each other - that&amp;rsquo;s its mission.&lt;/p>
&lt;h2 id="tls-ssl-https">
&lt;a class="heading-anchor-link" href="#tls-ssl-https">TLS, SSL, HTTPS&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tls-ssl-https"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Security matters. For WebSocket, you&amp;rsquo;ll see WS vs WSS; under HTTPS, use WSS.
What are TLS, SSL, and HTTPS?&lt;/p>
&lt;ul>
&lt;li>TLS (Transport Layer Security) and its predecessor SSL (Secure Sockets Layer) are security protocols that provide confidentiality and integrity.&lt;/li>
&lt;li>HTTPS is HTTP over TLS/SSL, providing encrypted transport and authentication.&lt;/li>
&lt;li>HTTPS is also known as HTTP over TLS.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-19-164130.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="websocket-sockjs-stomp">
&lt;a class="heading-anchor-link" href="#websocket-sockjs-stomp">WebSocket, SockJS, STOMP&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="websocket-sockjs-stomp"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>WebSocket is a browser/server full-duplex communication technology (application layer) built on TCP that reuses the HTTP handshake.&lt;/li>
&lt;li>WebSocket is an application-layer transport protocol that enables full-duplex comms over a single TCP connection.&lt;/li>
&lt;li>SockJS is a browser JavaScript library that provides a consistent, cross-browser API, falling back when WebSocket isn&amp;rsquo;t available (e.g., to polling). Spring supports SockJS.&lt;/li>
&lt;li>STOMP is a messaging protocol; since WebSocket doesn&amp;rsquo;t define message format, STOMP standardizes it.&lt;/li>
&lt;/ul>
&lt;p>My stack is React + Spring Boot, so I use WebSocket + SockJS + STOMP.&lt;/p>
&lt;h2 id="osi-seven-layer-model">
&lt;a class="heading-anchor-link" href="#osi-seven-layer-model">OSI seven-layer model&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="osi-seven-layer-model"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Open System Interconnection Model.&lt;/p>
&lt;p>I remembered it from college (Xie Xiren&amp;rsquo;s &amp;ldquo;Computer Networks&amp;rdquo;). A quick refresher when I saw &amp;ldquo;application layer&amp;rdquo; again.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-19-164957.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>The OSI seven-layer model is conceptual.&lt;/li>
&lt;li>In practice, we often use five layers (presentation/session are collapsed/omitted).&lt;/li>
&lt;/ul>
&lt;h2 id="where-websocket-meets-http">
&lt;a class="heading-anchor-link" href="#where-websocket-meets-http">Where WebSocket meets HTTP&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="where-websocket-meets-http"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>From connection, subscription, sending/receiving messages, to disconnecting - HTTP is still involved.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-19-191659.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ul>
&lt;li>The connection starts as an HTTP GET request.&lt;/li>
&lt;li>Then the WebSocket connection is established (status 101) and full-duplex comms happen there.&lt;/li>
&lt;li>A single logical session involves two requests: one HTTP, one WebSocket.&lt;/li>
&lt;/ul>
&lt;h3 id="useful-status-code">
&lt;a class="heading-anchor-link" href="#useful-status-code">Useful status code&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="useful-status-code"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>We all know the five HTTP status code classes, but 1xx is rare in RESTful work. You&amp;rsquo;ll see it here.&lt;/p>
&lt;h4 id="101">101&lt;/h4>&lt;blockquote>
&lt;p>HTTP 101 Switching Protocol indicates the server is switching protocols as requested via the Upgrade header. The response includes an Upgrade header indicating the target protocol.&lt;/p>
&lt;/blockquote>
&lt;h2 id="http-09---the-web-is-born">
&lt;a class="heading-anchor-link" href="#http-09---the-web-is-born">HTTP 0.9 - The Web is born&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="http-09---the-web-is-born"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Some history:&lt;/p>
&lt;ol>
&lt;li>HTTP 0.9 was proposed in 1991. Same year as my birth - easy to remember.&lt;/li>
&lt;li>0.9 supported only GET; POST/PUT arrived in 1.0.&lt;/li>
&lt;li>Today 1.1 is mainstream. HTTP/2 adds multiplexing; many sites enable it (mine too).&lt;/li>
&lt;li>HTTP/3 is coming, using QUIC over UDP instead of TCP. Adoption will be slower since it changes the transport layer.&lt;/li>
&lt;/ol>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-19-194115.jpeg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>My understanding is still shallow; learning continues through practice.&lt;/li>
&lt;li>The book is thorough and covers the fundamentals well.&lt;/li>
&lt;li>Reading fills knowledge gaps and is a way to &amp;ldquo;talk&amp;rdquo; with experts at a distance.&lt;/li>
&lt;/ol>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://juejin.im/post/5b7fd02d6fb9a01a196f6276" target="_blank" rel="noopener">Using SockJS in Vue for WebSocket communication&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://zh.wikipedia.org/wiki/OSI%E6%A8%A1%E5%9E%8B" target="_blank" rel="noopener">OSI model&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.chainnews.com/articles/401950499827.htm" target="_blank" rel="noopener">HTTP evolution notes (http0.9, http1.0, http1.1, http2, http3)&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Implementing WebSocket in Projects</title><link>https://en.1991421.cn/2020/04/16/websocket/</link><pubDate>Thu, 16 Apr 2020 22:57:20 +0800</pubDate><guid>https://en.1991421.cn/2020/04/16/websocket/</guid><description>&lt;blockquote>
&lt;p>Recently, our project had a requirement where users open a tab from our System A to operate System B, and when they click a certain operation button, it calls back our system&amp;rsquo;s API to change some data. We needed to execute a series of actions when events occur, such as page refreshing.
The underlying requirement actually tells us that our system needs the ability for the backend to actively push messages to the frontend. How to achieve this? WebSocket.&lt;/p>
&lt;/blockquote>
&lt;p>So, I began building support for it.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-16-235427.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="tech-stack">
&lt;a class="heading-anchor-link" href="#tech-stack">Tech Stack&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tech-stack"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>First, let me introduce the current project&amp;rsquo;s tech stack:&lt;/p>
&lt;ul>
&lt;li>React &lt;code>v16.4.2&lt;/code>&lt;/li>
&lt;li>SpringBoot &lt;code>v2.1.6.RELEASE&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>WebSocket technology itself is quite mature, so configuration and development for these two areas isn&amp;rsquo;t very difficult. Here are the key code blocks:&lt;/p>
&lt;h2 id="springboot">
&lt;a class="heading-anchor-link" href="#springboot">SpringBoot&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="springboot"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="nd">@Configuration&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nd">@EnableWebSocketMessageBroker&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">class&lt;/span> &lt;span class="nc">WebSocketConfig&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">implements&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">WebSocketMessageBrokerConfigurer&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nd">@Override&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">configureMessageBroker&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">MessageBrokerRegistry&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">enableSimpleBroker&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;/topic&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">setApplicationDestinationPrefixes&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;/app&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nd">@Override&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">registerStompEndpoints&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">StompEndpointRegistry&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">registry&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">registry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">addEndpoint&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;/websocket&amp;#34;&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="na">setAllowedOrigins&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;*&amp;#34;&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="na">withSockJS&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="nd">@RestController&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">class&lt;/span> &lt;span class="nc">GreetingController&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">private&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">final&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">SimpMessagingTemplate&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">simpMessagingTemplate&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">GreetingController&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">SimpMessagingTemplate&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">simpMessagingTemplate&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">simpMessagingTemplate&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">simpMessagingTemplate&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nd">@MessageMapping&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;/hello&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nd">@SendTo&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;/topic/greetings&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Greeting&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">greeting&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">HelloMessage&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">message&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">throws&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Exception&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">System&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">out&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">println&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Request: get message: &amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">message&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Greeting&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Response: Hello, &amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">HtmlUtils&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">htmlEscape&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">message&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getName&lt;/span>&lt;span class="p">())&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;!&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nd">@GetMapping&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;/broadcast&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">sendBroadcastCommand&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nd">@RequestParam&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">command&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">simpMessagingTemplate&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">convertAndSend&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;/topic/broadcast&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">command&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">command&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="react">
&lt;a class="heading-anchor-link" href="#react">React&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="react"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;static/js/stomp.min.js&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;static/js/sockjs-1.0.0.min.js&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">watchBroadcast() {&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">socket&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">SockJS&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/websocket&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">client&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">Stomp&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">over&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">socket&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">client&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">connect&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">()&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">client&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">subscribe&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/topic/broadcast&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">res&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">body&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="result">
&lt;a class="heading-anchor-link" href="#result">Result&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="result"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When the &lt;code>/broadcast&lt;/code> API is called, the backend sends messages to the frontend.&lt;/p>
&lt;p>It&amp;rsquo;s that simple, but there are still some pitfalls in actual development. Let&amp;rsquo;s continue:&lt;/p>
&lt;h2 id="important-notes">
&lt;a class="heading-anchor-link" href="#important-notes">Important Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="important-notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>If the backend has &lt;code>interceptors&lt;/code>, remember to set up a whitelist for paths like &lt;code>/websocket&lt;/code>, otherwise you&amp;rsquo;ll get a &lt;code>302&lt;/code> error.&lt;/li>
&lt;li>&lt;code>SocketJS versions need to match between frontend and backend&lt;/code>. Here my backend SocketJS version is &lt;code>1.0.0&lt;/code>, so the frontend sockjs must also be &lt;code>1.0.0&lt;/code>, otherwise compatibility errors will occur.&lt;/li>
&lt;li>During development, I encountered an issue where everything worked fine locally but returned a 500 error when deployed. The reason was that deployment used &lt;code>spring-boot-starter-undertow&lt;/code>, which wasn&amp;rsquo;t the container used locally. I ended up removing it. Note that undertow should be supported, but it might be a version issue.&lt;/li>
&lt;li>In my scenario, the backend API is called and then sends messages to the frontend, so I&amp;rsquo;m using GetMapping and simpMessagingTemplate together. If you need two-way communication, the first example is sufficient. Testing with both GetMapping and SendTo annotations didn&amp;rsquo;t work, so it seems this approach is necessary for this scenario.&lt;/li>
&lt;li>WebSocket doesn&amp;rsquo;t add new port numbers, still using 80 and 443, but since communication uses the WS protocol, container layers like Nginx and browser clients need to support it.&lt;/li>
&lt;li>Multiple connections can be established for the same service, and multiple subscriptions can be made for the same event, so be careful to avoid duplicate processing issues and wasted resources.&lt;/li>
&lt;/ol>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Why do we need WebSocket? Consider this statement: &amp;ldquo;HTTP protocol has a flaw: communication can only be initiated by the client, while WebSocket enables two-way communication between web frontend and backend.&amp;rdquo; So when to use it is quite clear.&lt;/li>
&lt;li>After implementing WebSocket in our project, similar requirements became much simpler (such as server-side directional collection of client information), making it worthwhile.&lt;/li>
&lt;/ul>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="http://www.ruanyifeng.com/blog/2017/05/websocket.html" target="_blank" rel="noopener">WebSocket Tutorial&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://stackoverflow.com/questions/40988030/what-is-the-difference-between-websocket-and-stomp-protocols/48373153" target="_blank" rel="noopener">What is the difference between WebSocket and STOMP protocols?&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://juejin.im/post/5da95a745188252ba420ab39#comment" target="_blank" rel="noopener">Fully Understanding the Differences and Connections between TCP/UDP, HTTP Long Connection, Websocket, SockJS/Socket.IO, and STOMP&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Playing with ThinkPad X1 Carbon 2019</title><link>https://en.1991421.cn/2020/04/06/thinkpad-x1-carbon-2019/</link><pubDate>Mon, 06 Apr 2020 11:06:48 +0800</pubDate><guid>https://en.1991421.cn/2020/04/06/thinkpad-x1-carbon-2019/</guid><description>&lt;blockquote>
&lt;p>I got the X1 before the New Year, but due to account issues, it sat unused for 2 months - so frustrating! After the holidays, customer service reinstalled the system, and I finally got it in my hands recently. Since my main machine is still a Mac, this machine inevitably serves as my backup.&lt;/p>
&lt;p>After playing with it lightly for a few hours, I&amp;rsquo;ll record my operations and thoughts here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-06-111821.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Note: &lt;code>The configuration I got is 7th generation + i7 + 16GB + 2TB, top configuration. X1 currently supports a maximum of 16GB memory, developers please take note&lt;/code>&lt;/p>
&lt;h2 id="x1s-hardware-build-quality">
&lt;a class="heading-anchor-link" href="#x1s-hardware-build-quality">X1&amp;rsquo;s Hardware Build Quality&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="x1s-hardware-build-quality"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Having extensively used MBPs, from the 2015 13&amp;quot; -&amp;gt; 15&amp;quot; to the current 16&amp;quot;, and lightly used the Surface Laptop, facing the X1&amp;rsquo;s appearance, my subjective feeling isn&amp;rsquo;t particularly amazed &lt;code>after all, we've seen the world, right&lt;/code>.&lt;/p>
&lt;p>But it&amp;rsquo;s absolutely high-value and can compete with MBP and Surface.&lt;/p>
&lt;p>Let me list what I consider the pros and cons&lt;/p>
&lt;h3 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Good looks - appearance is justice&lt;/li>
&lt;li>Lightweight, can compete with Surface Laptop&lt;/li>
&lt;li>Rich ports, so you don&amp;rsquo;t have to buy a new laptop and invest in a bunch of additional cables. Apple has always been terrible at this and never been surpassed&lt;/li>
&lt;li>180-degree flip - cool&lt;/li>
&lt;li>Fingerprint + face recognition, quick login&lt;/li>
&lt;/ol>
&lt;h3 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Battery life still can&amp;rsquo;t compete with Mac&lt;/li>
&lt;li>Software ecosystem is still lacking, can&amp;rsquo;t help it, same with Surface&lt;/li>
&lt;/ol>
&lt;p>In summary, a beautiful &amp;amp; excellent laptop&lt;/p>
&lt;h2 id="software-level-polishing">
&lt;a class="heading-anchor-link" href="#software-level-polishing">Software Level Polishing&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="software-level-polishing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After getting Windows, I started quickly installing a series of software to improve productivity. I recommend this &lt;a href="https://github.com/Awesome-Windows/Awesome" target="_blank" rel="noopener">software list&lt;/a> where you can find good software to try.&lt;/p>
&lt;h3 id="must-install-software">
&lt;a class="heading-anchor-link" href="#must-install-software">Must-Install Software&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="must-install-software"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The following are several software I personally need:&lt;/p>
&lt;ol>
&lt;li>Evernote&lt;/li>
&lt;li>Chrome&lt;/li>
&lt;li>Clash&lt;/li>
&lt;li>Listary&lt;/li>
&lt;li>Sogou Pinyin Input Method&lt;/li>
&lt;li>Snipaste&lt;/li>
&lt;li>Visual Studio Code&lt;/li>
&lt;/ol>
&lt;p>Actual Windows usage involves many personalized settings, which I won&amp;rsquo;t elaborate on here. My ongoing summary is &lt;a href="https://github.com/alanhe421/others-note/issues?q=is%3Aissue&amp;#43;is%3Aopen&amp;#43;label%3AWindows" target="_blank" rel="noopener">here&lt;/a>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020/2020-04-06-114840.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ol>
&lt;li>Spent a few hours on initial configuration, currently serves as my backup machine, which is acceptable&lt;/li>
&lt;li>What&amp;rsquo;s next is to continuously fine-tune it through actual usage.&lt;/li>
&lt;/ol></description></item><item><title>lodash isEmpty</title><link>https://en.1991421.cn/2020/03/07/lodashisempty/</link><pubDate>Sat, 07 Mar 2020 22:29:19 +0800</pubDate><guid>https://en.1991421.cn/2020/03/07/lodashisempty/</guid><description>&lt;blockquote>
&lt;p>As mentioned in a previous post, I really dislike lodash because when something can be implemented natively and efficiently, using lodash often just shows laziness and weak JS fundamentals. But if things are clear enough, using it appropriately is fine. After all, why reinvent the wheel?&lt;/p>
&lt;/blockquote>
&lt;p>Today I looked at the source code of &lt;code>isEmpty&lt;/code> because I had some misunderstandings about this function. For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isEmpty&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isEmpty&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;1&amp;#39;&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// false
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="isempty">
&lt;a class="heading-anchor-link" href="#isempty">isEmpty&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="isempty"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The official docs say:&lt;/p>
&lt;blockquote>
&lt;p>Checks if value is an empty object, collection, map, or set.&lt;/p>
&lt;p>Objects are considered empty if they have no own enumerable string keyed properties.&lt;/p>
&lt;p>Array-like values such as arguments objects, arrays, buffers, strings, or jQuery-like collections are considered empty if they have a length of 0. Similarly, maps and sets are considered empty if they have a size of 0.&lt;/p>
&lt;/blockquote>
&lt;p>So it is mainly used to determine empty objects, collections, and array-like values.&lt;/p>
&lt;h2 id="examples">
&lt;a class="heading-anchor-link" href="#examples">Examples&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="examples"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isEmpty&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isEmpty&lt;/span>&lt;span class="p">({}));&lt;/span> &lt;span class="c1">// true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isEmpty&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isEmpty&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">undefined&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isEmpty&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// true
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="source-code">
&lt;a class="heading-anchor-link" href="#source-code">Source Code&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="source-code"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Let&amp;rsquo;s look at how these cases are judged in the source:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">isEmpty&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">true&lt;/span> &lt;span class="c1">// null, undefined return true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">isArrayLike&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="nb">Array&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isArray&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="k">typeof&lt;/span> &lt;span class="nx">value&lt;/span> &lt;span class="o">===&lt;/span> &lt;span class="s1">&amp;#39;string&amp;#39;&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="k">typeof&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">splice&lt;/span> &lt;span class="o">===&lt;/span> &lt;span class="s1">&amp;#39;function&amp;#39;&lt;/span> &lt;span class="o">||&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">isBuffer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="nx">isTypedArray&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="nx">isArguments&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="o">!&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span> &lt;span class="c1">// &amp;#39;&amp;#39; returns true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">tag&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">getTag&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">tag&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s1">&amp;#39;[object Map]&amp;#39;&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="nx">tag&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s1">&amp;#39;[object Set]&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="o">!&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">size&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">isPrototype&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="o">!&lt;/span>&lt;span class="nb">Object&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">keys&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">length&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kr">const&lt;/span> &lt;span class="nx">key&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">hasOwnProperty&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">call&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">key&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">false&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">true&lt;/span> &lt;span class="c1">// number 1, {} return true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="details">
&lt;a class="heading-anchor-link" href="#details">Details&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="details"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>null == undefined&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="kc">undefined&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="o">===&lt;/span>&lt;span class="kc">undefined&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// false
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The equality check uses &lt;code>==&lt;/code> instead of &lt;code>===&lt;/code>. Note that &lt;code>null == undefined&lt;/code> is true. This is understandable since both mean empty values.&lt;/p>
&lt;ol start="2">
&lt;li>
&lt;p>Object.prototype.toString()&lt;/p>
&lt;p>The &lt;code>getTag&lt;/code> method mainly uses &lt;code>Object.prototype.toString(value)&lt;/code>.&lt;/p>
&lt;p>The official docs say the &lt;code>toString()&lt;/code> method returns a string representing the object.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">a&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">toString&lt;/span>&lt;span class="p">());&lt;/span> &lt;span class="err">\\&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="nx">object&lt;/span> &lt;span class="nb">Object&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html" target="_blank" rel="noopener">Difference between undefined and null&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>query-string@5 vs 6</title><link>https://en.1991421.cn/2020/02/09/query-string-5-vs-6/</link><pubDate>Sun, 09 Feb 2020 19:13:58 +0800</pubDate><guid>https://en.1991421.cn/2020/02/09/query-string-5-vs-6/</guid><description>&lt;blockquote>
&lt;p>query-string is a commonly used frontend library for parsing and stringifying URL query parameters. Normally, we can simply install and use the latest version 6.x. However, I once encountered a white screen incident that was ultimately traced back to compatibility issues with v6. This article focuses on clarifying the differences between v5 and v6, and their impact on web development.&lt;/p>
&lt;/blockquote>
&lt;h2 id="official-documentation-on-5-vs-6-differences">
&lt;a class="heading-anchor-link" href="#official-documentation-on-5-vs-6-differences">Official Documentation on 5 vs 6 Differences&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="official-documentation-on-5-vs-6-differences"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>This module targets Node.js 6 or later and the latest version of Chrome, Firefox, and Safari. If you want support for older browsers, or, if your project is using create-react-app v1, use version 5: npm install query-string@5.&lt;/p>
&lt;/blockquote>
&lt;p>Looking at the Git commit history, I noticed the first v6 commit message. What exactly are &amp;ldquo;modern browsers&amp;rdquo; and which versions are supported?&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://i.imgur.com/pk3lX06.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Conclusion: &lt;em>The documentation is vague and has pitfalls.&lt;/em>&lt;/p>
&lt;h2 id="code-analysis">
&lt;a class="heading-anchor-link" href="#code-analysis">Code Analysis&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="code-analysis"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>To accurately understand the differences between v5 and v6, we need to examine the code directly.&lt;/p>
&lt;h3 id="changelog">
&lt;a class="heading-anchor-link" href="#changelog">ChangeLog&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="changelog"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Here are the main changes observed in v6 from the source code:&lt;/p>
&lt;ol>
&lt;li>Removed the &lt;a href="https://github.com/sindresorhus/object-assign#readme" target="_blank" rel="noopener">object-assign third-party implementation&lt;/a> and switched to native &lt;code>Object.assign&lt;/code>&lt;/li>
&lt;li>Used const for constant declarations&lt;/li>
&lt;li>Used arrow function syntax sugar&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>const compatibility: IE11+ [including 11]&lt;/li>
&lt;li>Object.assign and arrow functions: Not supported in IE&lt;/li>
&lt;/ul>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Without adding compatibility files, v6 does not support IE, while v5 does&lt;/p>
&lt;/li>
&lt;li>
&lt;p>React framework also doesn&amp;rsquo;t support IE without compatibility files. To support IE11, you need to add the following files:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="s1">&amp;#39;react-app-polyfill/ie11&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="s1">&amp;#39;react-app-polyfill/stable&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;p>One of the problems that polyfill solves is &lt;code>Object.assign&lt;/code>, so if our web target is to support IE11, the added compatibility files can completely resolve query-string&amp;rsquo;s issues. If IE11 support is not needed, there&amp;rsquo;s even less to worry about - just upgrade directly.&lt;/p>
&lt;ul>
&lt;li>Since query-string v6 switched to using native &lt;code>Object.assign&lt;/code>, the bundle size is definitely further reduced, although this is minimal, but it&amp;rsquo;s good to know.&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>With browser standardization, and without considering IE as a problematic teammate, it seems that Safari, Edge, Chrome, and Firefox compatibility isn&amp;rsquo;t an issue. However, understanding compatibility remains an essential skill for frontend developers.&lt;/p></description></item><item><title>Investigating Real‑Time Search Result Errors</title><link>https://en.1991421.cn/2020/02/09/investigation-realtime-search-error/</link><pubDate>Sun, 09 Feb 2020 16:31:20 +0800</pubDate><guid>https://en.1991421.cn/2020/02/09/investigation-realtime-search-error/</guid><description>&lt;h2 id="problem">
&lt;a class="heading-anchor-link" href="#problem">Problem&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="problem"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>用一个例子来描述吧，当用户输入关键词A，触发了检索，一秒钟后，用户输入了关键词 B，触发了检索，这时A检索结果回来了，呈现出来了列表展示，用户诧异，为何输入的B，返回了A结果，再过一会儿B结果回来。用户在可视化的情况下，看到了错误的结果，紧接着看到了正确的结果。&lt;/p>
&lt;h2 id="analysis">
&lt;a class="heading-anchor-link" href="#analysis">Analysis&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="analysis"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>接口慢是个问题，但是除了接口慢，也可以看到整个的实时检索存在设计缺陷。&lt;/p>
&lt;ol>
&lt;li>当触发了第二次请求时，第一次请求如果还在请求中应该中断，这样对于开销来说小一些&lt;/li>
&lt;li>用户之所以会误认为A结果集是用户输入B的结果，还有一个问题是，是否当执行B检索时，就不应该呈现结果集，通过loading等形式呈现给用户还正在检索&lt;/li>
&lt;/ol>
&lt;h3 id="baidus-instant-search">
&lt;a class="heading-anchor-link" href="#baidus-instant-search">Baidu’s instant search&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="baidus-instant-search"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>百度比如输入关键词时，推荐列表并没有loading动画，我想根本原因是因为足够的快，所以不需要有loading&lt;/p>
&lt;h3 id="impact-of-canceling-on-the-backend">
&lt;a class="heading-anchor-link" href="#impact-of-canceling-on-the-backend">Impact of canceling on the backend&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="impact-of-canceling-on-the-backend"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>如上，当我们取消了一个已经发出的请求，但是因为请求本身是个异步的过程，所以&lt;code>后端还是会把这个请求处理流程走完&lt;/code>。所以严格来说，我们取消了请求，对于前端的开销有所减小，但是对于后端无任何影响。&lt;/p>
&lt;h2 id="solutions">
&lt;a class="heading-anchor-link" href="#solutions">Solutions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="solutions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>执行新的请求时，如果老的请求还在进行，进行取消&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://i.imgur.com/mrPXGy6.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>前端的请求类库，我使用的&lt;code>axios&lt;/code>,而本身类库提供了cancel的方案，所以在全局拦截器里进行下配置即可。具体代码可参考&lt;a href="https://gist.github.com/alanhe421/52d2a8a04e4695d158ec61ba7977cf3f" target="_blank" rel="noopener">这里&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>执行请求时，增加loading显示，让用户意识到当前的结果集是历史的，最新的正在检索中&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://i.imgur.com/JxHqYQ1.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>经过以上的方案处理，总结下。&lt;/p>
&lt;ol>
&lt;li>不会呈现错误的结果给用户&lt;/li>
&lt;li>支持了取消pending请求，节约了一定的前端性能开销&lt;/li>
&lt;li>除了上述的两点，也可以对于检索增加防抖处理，比如延迟1秒执行检索，确保高频输入不触发额外的检索。&lt;/li>
&lt;/ol>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.cnblogs.com/QianDingwei/p/11403916.html" target="_blank" rel="noopener">取消功能的设计与实现&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://segmentfault.com/a/1190000021290514" target="_blank" rel="noopener">axios如何取消重复请求&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Learning Retrospectives</title><link>https://en.1991421.cn/2020/01/31/retro/</link><pubDate>Fri, 31 Jan 2020 13:05:21 +0800</pubDate><guid>https://en.1991421.cn/2020/01/31/retro/</guid><description>&lt;blockquote>
&lt;p>Locked down over the Lunar New Year, I finally asked why our project (May 2019 → present) felt so exhausting. Morale was low, quality suffered, stakeholders were skeptical. The root issue: no regular retrospectives. To fix that post-holiday, I studied how to run good retros.&lt;/p>
&lt;/blockquote>
&lt;h2 id="takeaways">
&lt;a class="heading-anchor-link" href="#takeaways">Takeaways&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="takeaways"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Retros must be regular. We skipped them on three consecutive projects—an obvious warning sign.&lt;/li>
&lt;li>Surfacing problems is how we respect the team. It requires courage and the belief that exposing issues helps everyone.&lt;/li>
&lt;li>Prioritize ruthlessly. Instead of tackling dozens of problems, pick a few, assign owners, and make incremental progress—just like refactoring code.&lt;/li>
&lt;li>A retro is a meeting. Keep it efficient; meeting cost scales with headcount.&lt;/li>
&lt;/ol>
&lt;h3 id="our-retro-outline">
&lt;a class="heading-anchor-link" href="#our-retro-outline">Our Retro Outline&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="our-retro-outline"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Participants jot down “Went Well / Less Well / Puzzles” ahead of time (or during the first five minutes).&lt;/li>
&lt;li>Facilitator groups similar cards (5 minutes).&lt;/li>
&lt;li>Everyone gets five votes to prioritize issues (5 minutes).&lt;/li>
&lt;li>Discuss the top three items (10–15 minutes each) and define action items.&lt;/li>
&lt;li>Assign owners and deadlines.&lt;/li>
&lt;li>Send a recap with the board and action list.&lt;/li>
&lt;/ol>
&lt;p>Total runtime: ~60–90 minutes.&lt;/p>
&lt;h3 id="recommended-tool">
&lt;a class="heading-anchor-link" href="#recommended-tool">Recommended Tool&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="recommended-tool"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;a href="https://funretro.io/" target="_blank" rel="noopener">funretro.io&lt;/a> supports collaborative editing, voting, card merging, and anonymity—and it’s free.&lt;/p>
&lt;h2 id="closing-thoughts">
&lt;a class="heading-anchor-link" href="#closing-thoughts">Closing Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="closing-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Reflection beats mindless hustle. Slow down, examine the process, then run farther.&lt;/p>
&lt;h2 id="recommended-reading">
&lt;a class="heading-anchor-link" href="#recommended-reading">Recommended Reading&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="recommended-reading"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://github.com/linksgo2011/thought-tools-book/blob/master/chapters/chapter-01-retro.md" target="_blank" rel="noopener">Retro introduction (Chinese)&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.jianshu.com/p/b56bd71293ef" target="_blank" rel="noopener">Try the six thinking hats during retros (Chinese)&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://retrospectivewiki.org/index.php?title=6_Thinking_Hats_Retrospective" target="_blank" rel="noopener">6 Thinking Hats Retrospective&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Refactoring (2nd Edition) — Book Notes</title><link>https://en.1991421.cn/2020/01/30/7b2a517/</link><pubDate>Thu, 30 Jan 2020 12:24:42 +0800</pubDate><guid>https://en.1991421.cn/2020/01/30/7b2a517/</guid><description>&lt;blockquote>
&lt;p>Recently finished reading &amp;ldquo;Refactoring (2nd Edition)&amp;rdquo;. As a former ThoughtWorker, it would be embarrassing not to read a book by our company&amp;rsquo;s expert.&lt;/p>
&lt;p>I must say this book is excellently written. The problems and solutions mentioned in the book resonate strongly with my own experiences in continuous programming and project work, and I learned many valuable insights from reading it.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>I think this is what makes a good book - you genuinely feel that the points mentioned come from frontline experience summaries, not empty theories.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://i.imgur.com/dBlo7KX.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="key-takeaways">
&lt;a class="heading-anchor-link" href="#key-takeaways">Key Takeaways&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="key-takeaways"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>Some viewpoints and techniques from the book are worth savoring carefully and have high reference and learning value for actual programming. Here are some examples:&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>
&lt;p>When writing pipeline operations, I like to put the ending semicolon on its own line, making it easier to adjust the pipeline structure.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>When to refactor: The Rule of Three&lt;/p>
&lt;p>Don Roberts gave me a guideline: The first time you do something, just do it; the second time you do something similar, you wince at the duplication, but you do it anyway; the third time, you refactor. As the old saying goes: Three strikes and you refactor.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>When not to refactor&lt;/p>
&lt;ul>
&lt;li>When you don&amp;rsquo;t need to modify it, you don&amp;rsquo;t need to refactor. Refactoring is only valuable when you need to understand how it works.&lt;/li>
&lt;li>If rewriting is easier than refactoring, don&amp;rsquo;t refactor.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Attitude toward comments&lt;/p>
&lt;p>If you don&amp;rsquo;t know what to do, that&amp;rsquo;s when comments are well used. Besides recording future plans, comments can also mark areas where you&amp;rsquo;re not completely confident. You can write down &amp;ldquo;why you&amp;rsquo;re doing something&amp;rdquo; in comments. This information can help future modifiers, especially those forgetful folks.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Use pipelines instead of loops whenever possible&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Principles for extracting functions&lt;/p>
&lt;p>Once a function exceeds 6 lines, it starts to smell.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Refactoring isn&amp;rsquo;t a product of a certain phase, but something that needs to be done continuously&lt;/p>
&lt;/li>
&lt;li>
&lt;p>If a function has a return value internally, name this return variable &lt;code>result&lt;/code> to quickly understand the function&amp;rsquo;s intent&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The use of assertions isn&amp;rsquo;t limited to unit tests. JavaScript&amp;rsquo;s native support for assertions is only &lt;code>console.assert&lt;/code>, but it can also be used in actual business code. Appropriately adding assertions helps explain situations, and don&amp;rsquo;t be afraid - assertions shouldn&amp;rsquo;t impact system operation. &lt;code>Assertions are particularly helpful for finding error sources.&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Always remove dead code. If there&amp;rsquo;s a real possibility of needing it back, comment with the commit ID for retrieval&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The test of good code is whether people can easily modify it.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&amp;hellip;&lt;/p>
&lt;p>There are so many good insights that I&amp;rsquo;m only excerpting a few here.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>As mentioned above, a good book is one whose viewpoints align with your own thoughts, and that&amp;rsquo;s exactly how I feel. After reading this book, I have several thoughts:&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>
&lt;p>I&amp;rsquo;ve always believed the difference between an engineer and a code monkey is that one uses their brain while the other doesn&amp;rsquo;t - this is both a joke and the truth. Engineers abstract and examine problems, reflect and summarize, while code monkeys mostly just move bricks, essentially trading time for money with no other gains. But in today&amp;rsquo;s rapidly developing world, how many more days can this brick-moving continue? I think it should be quite frightening to contemplate.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>In the book&amp;rsquo;s preface, master Xiong Jie mentions that &lt;code>among the new generation of programmers, many focus on new tools, new frameworks, new business models, but very few focus on fundamentals like object-oriented programming, TDD, and refactoring&lt;/code>. Indeed, superficial technologies emerge endlessly, and we should learn them, but we should pay more attention to the substance - fundamentals and internal skills are the way to go. So this sentence in the preface touches the hearts of everyone with thoughts and feelings. How many people get caught up in form, reading massive amounts of APIs, memorizing version numbers, but what&amp;rsquo;s the use?&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The code readability we pursue is aimed at humans, not computers, so writing code should come with a sense of responsibility - not only being responsible for yourself but also for future others. So we can&amp;rsquo;t just say &amp;ldquo;whatever, as long as it works.&amp;rdquo;&lt;/p>
&lt;/li>
&lt;li>
&lt;p>After reading this book myself, I absorbed most of the abstract viewpoints and insights, but I can&amp;rsquo;t fully absorb all the specific refactoring techniques. I can only experience them in actual practice and training, while forming my own set of refactoring techniques.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>I recommend this book to everyone committed to writing good code - it&amp;rsquo;s worth reading.&lt;/p>
&lt;/li>
&lt;/ol></description></item><item><title>Tools I Bought in 2019</title><link>https://en.1991421.cn/2020/01/23/2019/</link><pubDate>Thu, 23 Jan 2020 23:24:31 +0800</pubDate><guid>https://en.1991421.cn/2020/01/23/2019/</guid><description>&lt;blockquote>
&lt;p>Tools need refinement and periodic upgrades. As the Lunar New Year approached, I reviewed the tools I bought and adjusted in 2019 (both hardware and software), the current capabilities, and the improvements achieved through tweaks.&lt;/p>
&lt;/blockquote>
&lt;p>While taking notes, I hope it helps fellow enthusiasts a bit.&lt;/p>
&lt;h2 id="homepod">
&lt;a class="heading-anchor-link" href="#homepod">HomePod&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="homepod"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I bought HomePod in April. The direct impulse came from Apple&amp;rsquo;s ad &lt;a href="https://www.youtube.com/watch?v=VYopZIlfer4" target="_blank" rel="noopener">Welcome Home&lt;/a>. No surprise, Apple&amp;rsquo;s ads always make you feel it&amp;rsquo;s amazing. The old AirPods ad with the dancer was the same.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://i.imgur.com/or4Bc2J.png"
alt="Tools I Bought in 2019 - Fig 1"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="features">
&lt;a class="heading-anchor-link" href="#features">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Voice-activated alarms&lt;/li>
&lt;li>Move your iPhone near the HomePod and it shows &lt;code>transfering to homepod&lt;/code>, then the audio automatically switches to HomePod. The experience is very cool.&lt;/li>
&lt;/ol>
&lt;h3 id="current-drawbacks">
&lt;a class="heading-anchor-link" href="#current-drawbacks">Current drawbacks&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-drawbacks"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>I say &amp;ldquo;current&amp;rdquo; because Apple could fix this via software updates. So let&amp;rsquo;s wait.&lt;/li>
&lt;li>The Apple Music catalog is still incomplete, and HomePod is limited to Apple Music. This hurts the experience.&lt;/li>
&lt;/ol>
&lt;h2 id="ipad-mini-5">
&lt;a class="heading-anchor-link" href="#ipad-mini-5">iPad mini 5&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ipad-mini-5"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Bought in July for &lt;code>3648 CNY&lt;/code>. I use it for reading, watching shows, and gaming. Great performance and portability. If you are considering an iPad, I &lt;strong>strongly recommend the cellular version&lt;/strong>, because using a phone hotspot is inconvenient, in my opinion.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://i.imgur.com/dXYeTWW.png"
alt="Tools I Bought in 2019 - Fig 2"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="features-1">
&lt;a class="heading-anchor-link" href="#features-1">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Reading&lt;/li>
&lt;/ol>
&lt;h2 id="bose-700">
&lt;a class="heading-anchor-link" href="#bose-700">Bose 700&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bose-700"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Bought in August. I use it during workdays and it blocks some office noise and distractions.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://i.imgur.com/pASHlmq.png"
alt="Tools I Bought in 2019 - Fig 3"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="features-2">
&lt;a class="heading-anchor-link" href="#features-2">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features-2"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Multi-level noise cancellation&lt;/li>
&lt;li>Multi-device connection, up to two devices&lt;/li>
&lt;li>Winter ear protection: in cold weather, it is much better than AirPods, based on my own test&lt;/li>
&lt;/ol>
&lt;h2 id="macbook-pro-16">
&lt;a class="heading-anchor-link" href="#macbook-pro-16">MacBook Pro 16&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="macbook-pro-16"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Bought in mid-December. Price &lt;code>20,619 CNY&lt;/code>, configuration 32G RAM + 512 SSD. The 16-inch narrow-bezel display is amazing. After purchase, it became my main production tool. Daily development is smooth.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2021/2021-01-02-212048.jpeg"
alt="Tools I Bought in 2019 - Fig 4"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="features-3">
&lt;a class="heading-anchor-link" href="#features-3">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features-3"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Development powerhouse&lt;/li>
&lt;li>Great for music and movies&lt;/li>
&lt;/ol>
&lt;h3 id="current-drawbacks-1">
&lt;a class="heading-anchor-link" href="#current-drawbacks-1">Current drawbacks&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="current-drawbacks-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Weight: if it could be lighter that would be better. At 2 kg bare, it is still heavy. Long backpack carry causes obvious soreness.&lt;/li>
&lt;li>Intermittent stutters: the performance is strong, but it still feels like it is not at full potential.&lt;/li>
&lt;/ul>
&lt;h2 id="datagrip">
&lt;a class="heading-anchor-link" href="#datagrip">DataGrip&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="datagrip"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Among work-related software, DataGrip was the most successful improvement this year. The payoff is much higher efficiency for DB operations. See my thoughts &lt;a href="https://1991421.cn/2019/10/01/6111fbb0/" target="_blank" rel="noopener">here&lt;/a>.&lt;/p>
&lt;h2 id="oreilly">
&lt;a class="heading-anchor-link" href="#oreilly">O&amp;rsquo;Reilly&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="oreilly"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>On the learning side, a successful tool this year was the O&amp;rsquo;Reilly Safari Online service. With the client app, I learned many technologies, and after a year of English reading, the language barrier seems smaller.&lt;/p>
&lt;h3 id="features-4">
&lt;a class="heading-anchor-link" href="#features-4">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features-4"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>O&amp;rsquo;Reilly App works across Web, iPhone, iPad&lt;/li>
&lt;li>The library is comprehensive, at least for tech&lt;/li>
&lt;li>I once emailed them about an app crash, and they responded actively&lt;/li>
&lt;/ol>
&lt;h3 id="purchase-tip">
&lt;a class="heading-anchor-link" href="#purchase-tip">Purchase tip&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="purchase-tip"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;blockquote>
&lt;p>I recommend using ACM membership to access Safari Online. It is only $75, and if you provide an address in a developing country, it can be reduced to $15. Personally tested.
&lt;a href="https://www.acm.org/membership/membership-benefits" target="_blank" rel="noopener">https://www.acm.org/membership/membership-benefits&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>Direct O&amp;rsquo;Reilly subscriptions are expensive, so I recommend the option above. My company provides access, so I have not used this plan, but I suggest giving it a try.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Tools exist to solve problems and improve efficiency and life, so they are worth investing in.&lt;/li>
&lt;li>Tools are great, but too many can be a burden. Do not chase tools for the sake of tools. The best tool is the one that fits your hand.&lt;/li>
&lt;/ol></description></item><item><title>2019 Year-End Summary</title><link>https://en.1991421.cn/2020/01/01/2019/</link><pubDate>Wed, 01 Jan 2020 21:25:14 +0800</pubDate><guid>https://en.1991421.cn/2020/01/01/2019/</guid><description>&lt;blockquote>
&lt;p>Strictly speaking, this post is one day late, so apologies to my 2019 self.&lt;/p>
&lt;p>Physical age may change, but the drive to fight is still burning, because this is the career I love.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2020-01-01-155453.jpg"
alt="2019 Year-End Summary - Fig 1"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="first-half">
&lt;a class="heading-anchor-link" href="#first-half">First half&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="first-half"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>From February to June, I stayed on a delivery enterprise project A. The tech stack was [React, Spring Boot, MongoDB, etc.]. I played a basic developer role, mainly frontend, but also took some backend tasks.&lt;/p>
&lt;p>The challenge of this project was integration and collaboration with many systems.&lt;/p>
&lt;p>Reflecting on how this project improved me: it was more about collaboration and steady execution. From a frontend perspective, there were many issues, but how to change and push those changes was the real problem.&lt;/p>
&lt;h3 id="a-painful-lesson">
&lt;a class="heading-anchor-link" href="#a-painful-lesson">A painful lesson&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="a-painful-lesson"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I once upgraded redux. Packaging had no issues, but QA found a serious problem. We eventually fixed it, but it taught me hard lessons.&lt;/p>
&lt;ol>
&lt;li>For version upgrades, caution is necessary. As the industry says, &lt;code>open source is free, but versions require caution&lt;/code>.&lt;/li>
&lt;li>You must read changelogs and understand them. Be clear about the impact scope of major, minor, and patch versions.&lt;/li>
&lt;li>Any major new change should be kept within your controllable range - for example, build a quick demo first, then promote it into the project.&lt;/li>
&lt;/ol>
&lt;h2 id="second-half">
&lt;a class="heading-anchor-link" href="#second-half">Second half&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="second-half"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Mid-year, I was transferred to a new Project B, and I was lucky to participate from start to current &lt;code>go-live in March&lt;/code>. For me, taking a project from zero to launch felt great, since I was a core contributor from start to finish.&lt;/p>
&lt;p>This project used the same tech stack as Project A. The difference was my role. I became the frontend lead. When I started, I reflected on why Project A had so many frontend issues, so I redesigned and adjusted the overall architecture. Here is what I did:&lt;/p>
&lt;ol>
&lt;li>&lt;code>IDEA plugins&lt;/code>: To make code review and commit standardization easier, I developed and improved two plugins. That made me familiar with the IDEA plugin mechanism, and I could solve some manual work at this layer.&lt;/li>
&lt;li>&lt;code>Frontend hooks&lt;/code>: The overall frontend hook mechanism became more robust - static analysis, code style checks, commit message format checks, and UT when pushing upstream. As a result, if a commit goes through, it&amp;rsquo;s hard to fail in Jenkins. &amp;ldquo;Hard&amp;rdquo; because Jenkins still sometimes fails to pull code, which causes a red build. That issue hasn&amp;rsquo;t been solved yet.&lt;/li>
&lt;li>&lt;code>Second-party packages&lt;/code>: The project has two web apps, and I felt there was a lot of repeated development in Project B. So I led the team to build shared packages. The goal was simple: DRY and an enterprise UI foundation. Version management followed standards strictly. Over time, this greatly improved productivity and safety.&lt;/li>
&lt;li>&lt;code>Frontend architecture&lt;/code>: Compared with Project A, Project B&amp;rsquo;s architecture has been stable so far, thanks to multiple small adjustments. There are still some design flaws &lt;code>that do not affect feature development&lt;/code>, such as putting all requests in the saga layer, forcing data into Redux. I&amp;rsquo;m still thinking about how to solve this.&lt;/li>
&lt;/ol>
&lt;p>At this point, the overall project is close to the end. The hardships in between are felt by everyone on the team. One word: tired. That tiredness shows in my weight gain, worsening eyesight, and serious physical exhaustion.&lt;/p>
&lt;h2 id="career-direction">
&lt;a class="heading-anchor-link" href="#career-direction">Career direction&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="career-direction"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After some struggle, I made a choice at year-end that didn&amp;rsquo;t feel too hard: I decided to leave TW.&lt;/p>
&lt;h3 id="tw-to-me">
&lt;a class="heading-anchor-link" href="#tw-to-me">TW to me&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tw-to-me"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The 1.5 years at TW gave me little, but also a lot. I don&amp;rsquo;t regret coming here. These thoughtful partners helped me learn a lot, &lt;code>except for a few&lt;/code>.&lt;/li>
&lt;li>I think the higher you climb, the smaller the circle becomes. Maybe one day I&amp;rsquo;ll return. Who knows.&lt;/li>
&lt;/ol>
&lt;h3 id="the-new-job">
&lt;a class="heading-anchor-link" href="#the-new-job">The new job&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-new-job"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>For the new role, I don&amp;rsquo;t have high expectations. I hope to stay grounded, keep doing my work happily, and focus more on outputting value and showing value.&lt;/p>
&lt;p>Of course, my personality means I often think in an immature or unstable way. If reality isn&amp;rsquo;t what I want, I can only keep looking.&lt;/p>
&lt;h3 id="my-attitude-toward-job-changes">
&lt;a class="heading-anchor-link" href="#my-attitude-toward-job-changes">My attitude toward job changes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-attitude-toward-job-changes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I used to resist changing jobs and thought, &amp;ldquo;Why be so picky?&amp;rdquo; But today I think differently. If a person and a job don&amp;rsquo;t fit, you can&amp;rsquo;t change the environment. Maybe you&amp;rsquo;re just out of place. So sometimes changing is right. Just do your job well while you&amp;rsquo;re there.&lt;/p>
&lt;p>We respect work, and we also respect ourselves.&lt;/p>
&lt;h2 id="family">
&lt;a class="heading-anchor-link" href="#family">Family&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="family"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I&amp;rsquo;m getting older, and my family is no exception. Because of work, I&amp;rsquo;m often far from home. Sometimes I wonder, why? But this is probably the best choice for now. I control my fate. As someone in IT, if I&amp;rsquo;m not in a city full of opportunities, where else should I go?&lt;/p>
&lt;p>What I can do is care for and love my family more. I now call home almost every day. If I have time to meet friends, why not spend more time caring for my family?&lt;/p>
&lt;p>During my annual leave, I took my grandmother to Chongqing. Forgive me for being clueless - I didn&amp;rsquo;t realize how hilly that city is, and it wore her out. But she was still happy because she rarely traveled. This year I hope to take her to Xiamen or Sanya.&lt;/p>
&lt;h2 id="habits">
&lt;a class="heading-anchor-link" href="#habits">Habits&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="habits"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="writing-blogs">
&lt;a class="heading-anchor-link" href="#writing-blogs">Writing blogs&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="writing-blogs"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>My blogging output increased significantly this year - applause to myself. I write for a few reasons: (1) to influence and share; to help the team understand issues, I summarize real project problems and solutions, so we don&amp;rsquo;t waste time repeating. (2) I found my blog traffic was decent via Google Analytics, so I introduced AdSense to try traffic monetization. I don&amp;rsquo;t care about the money yet, but I like this healthy way of monetizing knowledge.&lt;/p>
&lt;h3 id="reading">
&lt;a class="heading-anchor-link" href="#reading">Reading&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="reading"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;h3 id="medium">
&lt;a class="heading-anchor-link" href="#medium">Medium&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="medium"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I read Medium a lot in the first half of the year and less in the second half, but I still read it. Medium articles are generally high quality. It&amp;rsquo;s a good supplement beyond books, source code, and official docs.&lt;/p>
&lt;h3 id="oreilly">
&lt;a class="heading-anchor-link" href="#oreilly">O&amp;rsquo;Reilly&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="oreilly"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Since I started reading on the iPad mini I bought, I got hooked on this platform.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Foreign-language books&lt;/p>
&lt;p>After reading a few, the language barrier became smaller. The technical reading fluency I once hoped for is basically within reach.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Comprehensive and up-to-date books&lt;/p>
&lt;p>It feels like anything you can think of is there once you search. No need to say more.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="youtube">
&lt;a class="heading-anchor-link" href="#youtube">YouTube&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="youtube"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>YouTube is now my main source of technical videos. I realized videos and books each have their advantages; videos are a great supplement. So I got a YouTube membership this year and loved it.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Looking back on the year, it was exhausting and hard, but I made it through.&lt;/li>
&lt;li>Especially in the second half, physical output exceeded mental output. I didn&amp;rsquo;t like that, so I&amp;rsquo;m seeking change.&lt;/li>
&lt;li>In the new year, I want to enjoy life more, treat myself better, and keep traveling with my family.&lt;/li>
&lt;li>In the new year, I want to clarify my career path. I&amp;rsquo;ll be 29, and by 30 I should be settled down.&lt;/li>
&lt;/ul></description></item><item><title>PUT vs. PATCH in REST APIs</title><link>https://en.1991421.cn/2019/12/29/restfulputpatch/</link><pubDate>Sun, 29 Dec 2019 22:50:53 +0800</pubDate><guid>https://en.1991421.cn/2019/12/29/restfulputpatch/</guid><description>&lt;blockquote>
&lt;p>Teams often debate whether to differentiate between PUT and PATCH when designing APIs. If it’s a recurring question, it’s worth understanding properly.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019/2019-12-29-142044.jpg"
alt="https://static.1991421.cn/2019/2019-12-29-142044.jpg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>
Image source: &lt;a href="https://blog.eq8.eu/article/put-vs-patch.html" target="_blank" rel="noopener">https://blog.eq8.eu/article/put-vs-patch.html&lt;/a>&lt;/p>
&lt;h2 id="put-vs-patch">
&lt;a class="heading-anchor-link" href="#put-vs-patch">PUT vs. PATCH&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="put-vs-patch"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="put">
&lt;a class="heading-anchor-link" href="#put">PUT&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="put"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Full replacement of a resource.&lt;/p>
&lt;blockquote>
&lt;p>The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource…&lt;/p>
&lt;/blockquote>
&lt;h3 id="patch">
&lt;a class="heading-anchor-link" href="#patch">PATCH&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="patch"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Partial update of one or more fields.&lt;/p>
&lt;blockquote>
&lt;p>The PATCH method is similar to PUT except that the entity contains a list of differences between the original version of the resource identified by the Request-URI and the desired content of the resource after the PATCH action has been applied…&lt;/p>
&lt;/blockquote>
&lt;p>PATCH was introduced in HTTP/1.1. Full spec: &lt;a href="https://tools.ietf.org/html/rfc2068" target="_blank" rel="noopener">https://tools.ietf.org/html/rfc2068&lt;/a>&lt;/p>
&lt;h3 id="example">
&lt;a class="heading-anchor-link" href="#example">Example&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="example"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-http" data-lang="http">&lt;span class="line">&lt;span class="cl">&lt;span class="err">PUT /users/:id
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">{
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err"> &amp;#34;username&amp;#34;: &amp;#34;&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err"> &amp;#34;nickname&amp;#34;: &amp;#34;&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err"> &amp;#34;sex&amp;#34;: &amp;#34;male&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err"> &amp;#34;age&amp;#34;: 11,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err"> &amp;#34;address&amp;#34;: &amp;#34;xxxx&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">}
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-http" data-lang="http">&lt;span class="line">&lt;span class="cl">&lt;span class="err">PATCH /users/:id/address
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">{
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err"> &amp;#34;address&amp;#34;: &amp;#34;xxxx&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">}
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="why-bother-distinguishing">
&lt;a class="heading-anchor-link" href="#why-bother-distinguishing">Why bother distinguishing?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-bother-distinguishing"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>You &lt;em>could&lt;/em> skip PATCH and use PUT for everything, but you’ll hit a few issues.&lt;/p>
&lt;h3 id="updating-the-address-only">
&lt;a class="heading-anchor-link" href="#updating-the-address-only">Updating the address only&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="updating-the-address-only"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Two options:&lt;/p>
&lt;ol>
&lt;li>&lt;code>PUT /users/:id&lt;/code> with the full payload. Downsides: unnecessary data transfer, and the consumer must construct the entire resource shape even for a minor update. The larger the resource, the worse it gets.&lt;/li>
&lt;li>Add a dedicated endpoint like &lt;code>/users/:id/address&lt;/code> that only accepts the fields you want to change. Switch the method to PATCH and the intent becomes clear: it’s a partial update.&lt;/li>
&lt;/ol>
&lt;h3 id="updating-two-fields-nickname-and-sex">
&lt;a class="heading-anchor-link" href="#updating-two-fields-nickname-and-sex">Updating two fields (nickname and sex)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="updating-two-fields-nickname-and-sex"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Continuing the previous pattern: &lt;code>PATCH /users/:id/address&lt;/code> no longer fits. You might redefine it as:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-http" data-lang="http">&lt;span class="line">&lt;span class="cl">&lt;span class="err">PATCH /users/:id
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">{
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err"> &amp;#34;nickname&amp;#34;: &amp;#34;xxxx&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err"> &amp;#34;sex&amp;#34;: &amp;#34;female&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">}
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>That’s still reasonable.&lt;/p>
&lt;h3 id="arbitrary-fields">
&lt;a class="heading-anchor-link" href="#arbitrary-fields">Arbitrary fields&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="arbitrary-fields"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>You can allow any combination of fields, but you must validate the input server-side. A naive implementation that blindly merges the request body into the entity opens security holes—think of fields that should never be updated, such as IDs. Add a whitelist or schema validation before applying changes.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>PUT and PATCH are primarily about semantics. Modern tooling (axios, Spring, etc.) supports both, so choose the method that matches your scenario. Standards reflect lessons learned—follow them thoughtfully.&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html" target="_blank" rel="noopener">RESTful API Best Practices&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://restfulapi.net/resource-naming/" target="_blank" rel="noopener">REST Resource Naming Guide&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.jianshu.com/p/603158e777df" target="_blank" rel="noopener">Using PATCH for partial updates&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tools.ietf.org/html/rfc2068" target="_blank" rel="noopener">HTTP/1.1 specification&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Migrate to a New Mac with Time Machine</title><link>https://en.1991421.cn/2019/12/21/time-machinemac/</link><pubDate>Sat, 21 Dec 2019 12:04:18 +0800</pubDate><guid>https://en.1991421.cn/2019/12/21/time-machinemac/</guid><description>&lt;blockquote>
&lt;p>I recently bought a new Mac and used Time Machine to restore everything. The process was so smooth that I wanted to document it—maybe it’ll help you too.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;em>Note: The OS versions mentioned below were from the original migration, but the same process works today.&lt;/em>&lt;/p>
&lt;h2 id="prep">
&lt;a class="heading-anchor-link" href="#prep">Prep&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="prep"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Synology NAS running Time Machine; backup image came from MacBook Pro 2015 (macOS 10.14 Mojave)&lt;/li>
&lt;li>Target machine: MacBook Pro 2016 (macOS 10.15 Catalina)&lt;/li>
&lt;li>NAS and Mac on the same LAN&lt;/li>
&lt;/ul>
&lt;h2 id="start-the-migration">
&lt;a class="heading-anchor-link" href="#start-the-migration">Start the Migration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="start-the-migration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When you boot the new Mac, Setup Assistant offers to restore from Time Machine. Select the backup, choose what to transfer, and let it run. Mine took about four hours.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-12-21-124532.jpg"
alt="https://static.1991421.cn/2019-12-21-124532.jpg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-12-21-125059.png"
alt="https://static.1991421.cn/2019-12-21-125059.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="tips">
&lt;a class="heading-anchor-link" href="#tips">Tips&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tips"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>Source and target macOS versions don’t have to match (I migrated 10.14 → 10.15).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>If you see &lt;code>No Volumes found in backup&lt;/code>, retry; temporarily disconnect the old Mac from the NAS if it’s still connected.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-12-21-124645.png"
alt="https://static.1991421.cn/2019-12-21-124645.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="after-the-restore">
&lt;a class="heading-anchor-link" href="#after-the-restore">After the Restore&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="after-the-restore"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>A fresh Mac isn’t 100% ready immediately—there’s still some housekeeping:&lt;/p>
&lt;ol>
&lt;li>Sign in to your Apple ID.&lt;/li>
&lt;li>Re-authorize apps in &lt;strong>Security &amp;amp; Privacy&lt;/strong> (camera/mic/files, etc.).&lt;/li>
&lt;li>Some apps may fail to launch (WeChat did); reinstall if needed.&lt;/li>
&lt;li>License-activated apps need reactivation on new hardware.&lt;/li>
&lt;li>Wi-Fi may connect but not pass traffic—create a new Location in Network settings and reconnect.&lt;/li>
&lt;/ol>
&lt;h2 id="update">
&lt;a class="heading-anchor-link" href="#update">Update&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="update"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Both my new MacBook Air m4 and Mac mini m4 were restored from an old MacBook Pro via Time Machine—still fast and reliable.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Setting up a new Mac used to mean rebuilding everything from scratch—painful for developers. Time Machine on a NAS saved me at least a day of work. Highly recommended.&lt;/p>
&lt;ul>
&lt;li>Kudos to Apple.&lt;/li>
&lt;li>A ~$2K NAS with Time Machine support is far more convenient than manual external-drive backups.&lt;/li>
&lt;li>My first Mac (July 21, 2016) was life-changing—I’m not going back to Windows. It’s not just the OS; it’s the whole ecosystem.&lt;/li>
&lt;/ul>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://support.apple.com/HT201250" target="_blank" rel="noopener">Back up your Mac with Time Machine&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>How to Use Google Voice (Step-by-Step Guide)</title><link>https://en.1991421.cn/2019/11/02/googlevoice/</link><pubDate>Sat, 02 Nov 2019 21:15:37 +0800</pubDate><guid>https://en.1991421.cn/2019/11/02/googlevoice/</guid><description>&lt;blockquote>
&lt;p>Some foreign services require phone number binding, and domestic Chinese phone numbers are not supported. On the other hand, for services I frequently use like Telegram, while you can register with a domestic number, there are security risks - you know the privacy situation in China. In short, to safely and conveniently use these quality foreign services, I decided to get Google Voice.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-07-20-115327.jpeg"
alt="https://static.1991421.cn/2024/2024-07-20-115327.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="preparation-requirements">
&lt;a class="heading-anchor-link" href="#preparation-requirements">Preparation Requirements&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="preparation-requirements"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>GV account is essentially a Google account.&lt;/p>
&lt;ul>
&lt;li>Healthy network, can access the internet properly&lt;/li>
&lt;/ul>
&lt;h2 id="gv-purchase">
&lt;a class="heading-anchor-link" href="#gv-purchase">GV Purchase&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="gv-purchase"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I&amp;rsquo;ve tried to register for GV myself before, but it requires a US phone card, which is a complete blocker. Even if you could buy a phone card, you&amp;rsquo;d have to maintain it every month, which is too much hassle. So I ended up buying one on Taobao for &lt;code>11.8 RMB&lt;/code>. When purchasing, they&amp;rsquo;ll ask if you want &lt;code>transferable&lt;/code>. &lt;code>I recommend not choosing transferable - transfers carry the risk of account banning, you can look up the details separately.&lt;/code>&lt;/p>
&lt;p>&lt;strong>Update: If you can&amp;rsquo;t find it on Taobao/Xianyu, you can purchase through Telegram - just find any store. For example, the one I bought from before: @nexterastore.&lt;/strong>&lt;/p>
&lt;h2 id="gv-number-maintenance">
&lt;a class="heading-anchor-link" href="#gv-number-maintenance">GV Number Maintenance&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="gv-number-maintenance"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>If there are no calls or text messages for three consecutive months, the number will be reclaimed, so number maintenance is needed.&lt;/strong>&lt;/p>
&lt;p>You can keep it active by sending text messages, for example, send &lt;code>TRUMP&lt;/code> to 88022, or call Apple customer service at &lt;code>800–692–7753&lt;/code>&lt;/p>
&lt;h2 id="paid-calls">
&lt;a class="heading-anchor-link" href="#paid-calls">Paid Calls&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="paid-calls"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>GV can normally send/receive messages and make calls. You can install the corresponding app - Voice - on your phone.&lt;/p>
&lt;ol>
&lt;li>To use it normally, you still need a proxy, and it must be a proxy from the target country. For example, if my GV number is from the US, then the GV app must use a US proxy. Testing found that there&amp;rsquo;s no such restriction on PC.&lt;/li>
&lt;li>Besides free service calls, etc., other services require payment. For example, if two people contact each other via GV, if needed, then GV needs to be bound with payment.&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>After getting the GV virtual phone number, many services like Azure and Telegram can directly use this number. A whole category of problems gets solved, so it&amp;rsquo;s worth the investment.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>GV, like Apple US region accounts, will only become harder to apply for, so if you need it, get it done as soon as possible.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="related-materials">
&lt;a class="heading-anchor-link" href="#related-materials">Related Materials&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-materials"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.makeuseof.com/tag/deactivate-delete-telegram-account/" target="_blank" rel="noopener">How to Deactivate or Delete Your Telegram Account&lt;/a>&lt;/li>
&lt;li>[&lt;a href="https://www.vpsdawanjia.com/1548.html" target="_blank" rel="noopener">2019 Analysis of Several Feasible Solutions for Registering Google Voice&lt;/a>](&lt;a href="https://www.vpsdawanjia.com/1548.html" target="_blank" rel="noopener">https://www.vpsdawanjia.com/1548.html&lt;/a>)&lt;/li>
&lt;/ul></description></item><item><title>Redux in Action Key Takeaways</title><link>https://en.1991421.cn/2019/10/20/redux-in-action/</link><pubDate>Sun, 20 Oct 2019 22:00:47 +0800</pubDate><guid>https://en.1991421.cn/2019/10/20/redux-in-action/</guid><description>&lt;blockquote>
&lt;p>I spent two days reading &lt;a href="https://item.jd.com/33402169124.html" target="_blank" rel="noopener">Redux in Action&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-10-20-074400.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Combining the book with more than a year of React/Redux experience, I jotted down reflections—mostly small but important details to watch in real projects.&lt;/p>
&lt;h2 id="state-is-read-only">
&lt;a class="heading-anchor-link" href="#state-is-read-only">State Is Read-Only&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="state-is-read-only"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>We &lt;strong>should not&lt;/strong> mutate &lt;code>state&lt;/code> directly inside reducers (or sagas/effects). Technically we &lt;em>can&lt;/em>, but we shouldn’t. Mutating the original state doesn’t throw errors, yet React won’t re-render the components.&lt;/p>
&lt;p>A counterexample:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="k">case&lt;/span> &lt;span class="s1">&amp;#39;UPDATE_USER_AGE&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">state&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">age&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">state&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dispatch this action and inspect the state with Redux DevTools: the number increases, but the React component never updates because no re-render occurs.&lt;/p>
&lt;p>The state changed, but React didn’t notice. Why? Because of &lt;code>connect&lt;/code>.&lt;/p>
&lt;h3 id="connect-checks-references">
&lt;a class="heading-anchor-link" href="#connect-checks-references">&lt;code>connect&lt;/code> Checks References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="connect-checks-references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">mapStateToProps&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">state&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">user&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">state&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">user&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Redux uses a &lt;strong>shallow equality&lt;/strong> check. If the &lt;code>user&lt;/code> reference doesn’t change, &lt;code>mapStateToProps&lt;/code> keeps returning the same object, so React thinks nothing changed.&lt;/p>
&lt;p>Conclusion: never mutate state directly, or you invite bugs.&lt;/p>
&lt;h2 id="sync-vs-async">
&lt;a class="heading-anchor-link" href="#sync-vs-async">Sync vs. Async&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="sync-vs-async"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>In React-Redux + redux-thunk + redux-saga setups—or plain JavaScript—the sync/async story is unavoidable. Within Redux:&lt;/p>
&lt;ol>
&lt;li>Dispatching an action from the view to the store is synchronous, and components synchronously subscribe to store changes. However, React still has to run through lifecycle updates, so dispatching an action and immediately reading state from props doesn’t &lt;em>guarantee&lt;/em> you see the latest values. Remember, &lt;code>connect&lt;/code> ultimately calls &lt;code>setState&lt;/code>, and &lt;code>setState&lt;/code> is async.&lt;/li>
&lt;li>Inside redux-saga effects, dispatching an action and then calling &lt;code>select&lt;/code> to read state &lt;strong>does&lt;/strong> yield the latest value. As above, the pipeline is synchronous.&lt;/li>
&lt;li>redux-thunk lets actions return functions (even Promises). When you dispatch a function, you’re embracing asynchronous control flow.&lt;/li>
&lt;/ol>
&lt;h2 id="action-payload-naming">
&lt;a class="heading-anchor-link" href="#action-payload-naming">Action Payload Naming&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="action-payload-naming"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Example action creator:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">export&lt;/span> &lt;span class="kr">const&lt;/span> &lt;span class="nx">setBooksInfo&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">books&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;BOOKS_FETCH_SUCCEEDED&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">books&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A better practice is to wrap parameters inside &lt;code>payload&lt;/code>. Two benefits:&lt;/p>
&lt;ol>
&lt;li>You avoid naming collisions with the reserved &lt;code>type&lt;/code> field. If you ever need a field literally named &lt;code>type&lt;/code>, you can still place it under &lt;code>payload&lt;/code>.&lt;/li>
&lt;li>If you spread the action (excluding &lt;code>type&lt;/code>), &lt;code>...action&lt;/code> would otherwise pull in &lt;code>type&lt;/code>. With payload, you can safely destructure all custom fields.&lt;/li>
&lt;/ol>
&lt;p>That’s why Flux Standard Actions (FSA) recommend &lt;code>payload&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">export&lt;/span> &lt;span class="kr">const&lt;/span> &lt;span class="nx">setBooksInfo&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">books&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;BOOKS_FETCH_SUCCEEDED&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">payload&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">books&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>More details: &lt;a href="https://github.com/acdlite/flux-standard-action" target="_blank" rel="noopener">https://github.com/acdlite/flux-standard-action&lt;/a>&lt;/p>
&lt;h2 id="container-vs-presentational-components">
&lt;a class="heading-anchor-link" href="#container-vs-presentational-components">Container vs. Presentational Components&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="container-vs-presentational-components"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Redux popularized splitting components into containers and presentational pieces, often mirrored in a &lt;code>containers/&lt;/code> + &lt;code>components/&lt;/code> folder structure. Technically it separates Redux-aware components from pure UI.&lt;/p>
&lt;p>Personally I don’t love the pattern. React is ultimately an interaction library; every component serves the UI. I prefer organizing components by feature/usage and extracting shared pieces into &lt;code>shared/&lt;/code>. Whether a component connects to Redux should be guided by team conventions and code reviews, not directory hierarchy.&lt;/p>
&lt;p>Remember: Redux and React are just libraries. They don’t mandate folder structures. Adopt what works for your team.&lt;/p>
&lt;h2 id="redux-middleware-flow">
&lt;a class="heading-anchor-link" href="#redux-middleware-flow">Redux Middleware Flow&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="redux-middleware-flow"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;code>action&lt;/code> dispatch → middleware chain (e.g., &lt;code>middleware1&lt;/code>, &lt;code>middleware2&lt;/code>) → reducers update the store → connected components receive updates and re-render.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-10-20-092518.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="when-to-use-redux-saga-vs-redux-thunk">
&lt;a class="heading-anchor-link" href="#when-to-use-redux-saga-vs-redux-thunk">When to Use Redux-Saga vs. Redux-Thunk&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="when-to-use-redux-saga-vs-redux-thunk"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Use sagas for complex, long-running processes.&lt;/li>
&lt;li>Sagas and thunks can coexist; Redux accepts multiple middlewares.&lt;/li>
&lt;li>Both handle side effects. Anything a thunk can do, a saga can also do. For simple effects (e.g., a single network request), thunk is fine. For multi-step flows, sagas keep the code cleaner.&lt;/li>
&lt;/ul>
&lt;h2 id="performance-tips">
&lt;a class="heading-anchor-link" href="#performance-tips">Performance Tips&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="performance-tips"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>React and Redux are lightweight, but it’s still easy to waste cycles. A few points:&lt;/p>
&lt;ol>
&lt;li>Map only the slices of state a component actually needs. Redux state is a single tree, but subscribing to the entire root is overkill. You either never re-render (if references stay equal) or over-render unnecessarily.&lt;/li>
&lt;li>Choose between &lt;code>React.Component&lt;/code> and &lt;code>React.PureComponent&lt;/code> wisely. &lt;code>Component&lt;/code>’s &lt;code>shouldComponentUpdate&lt;/code> always returns true. &lt;code>PureComponent&lt;/code> shallowly compares props and state:&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">ctor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">prototype&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nx">ctor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">prototype&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">isPureReactComponent&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">!&lt;/span>&lt;span class="nx">shallowEqual&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">oldProps&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">newProps&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">!&lt;/span>&lt;span class="nx">shallowEqual&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">oldState&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">newState&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>shallowEqual&lt;/code> in turn checks keys and shallow value equality.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">shallowEqual&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">objA&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">objB&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">is&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">objA&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">objB&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">typeof&lt;/span> &lt;span class="nx">objA&lt;/span> &lt;span class="o">!==&lt;/span> &lt;span class="s1">&amp;#39;object&amp;#39;&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="nx">objA&lt;/span> &lt;span class="o">===&lt;/span> &lt;span class="kc">null&lt;/span> &lt;span class="o">||&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">typeof&lt;/span> &lt;span class="nx">objB&lt;/span> &lt;span class="o">!==&lt;/span> &lt;span class="s1">&amp;#39;object&amp;#39;&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="nx">objB&lt;/span> &lt;span class="o">===&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">keysA&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">Object&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">keys&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">objA&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">keysB&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">Object&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">keys&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">objB&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">keysA&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span> &lt;span class="o">!==&lt;/span> &lt;span class="nx">keysB&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kd">let&lt;/span> &lt;span class="nx">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nx">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="nx">keysA&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nx">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="nx">hasOwn&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">call&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">objB&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">keysA&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="o">||&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">!&lt;/span>&lt;span class="nx">is&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">objA&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">keysA&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">]],&lt;/span> &lt;span class="nx">objB&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">keysA&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">]]))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>PureComponent&lt;/code> adds this shallow comparison step during &lt;code>shouldComponentUpdate&lt;/code>. If you extend &lt;code>React.PureComponent&lt;/code>, don’t reimplement &lt;code>shouldComponentUpdate&lt;/code> yourself.&lt;/p>
&lt;h3 id="example">
&lt;a class="heading-anchor-link" href="#example">Example&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="example"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">export&lt;/span> &lt;span class="kr">class&lt;/span> &lt;span class="nx">NumberList&lt;/span> &lt;span class="kr">extends&lt;/span> &lt;span class="nx">React&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">PureComponent&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">render&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;render list&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">listItems&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">props&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">numbers&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">map&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="nx">number&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="nx">li&lt;/span> &lt;span class="nx">key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="nx">number&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">toString&lt;/span>&lt;span class="p">()}&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="nx">number&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="err">/li&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="nx">ul&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="nx">listItems&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="err">/ul&amp;gt;;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If the parent re-renders but the &lt;code>numbers&lt;/code> reference doesn’t change, &lt;code>NumberList&lt;/code> doesn’t re-render (no console output). Switch to &lt;code>React.Component&lt;/code>, and every parent render re-runs the child render method. React’s diffing prevents DOM churn, but calling &lt;code>render&lt;/code> still has a cost—avoid it when possible.&lt;/p>
&lt;h3 id="when-to-use-purecomponent">
&lt;a class="heading-anchor-link" href="#when-to-use-purecomponent">When to Use PureComponent&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="when-to-use-purecomponent"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Use &lt;code>PureComponent&lt;/code> when props and state are immutable. Otherwise fall back to &lt;code>Component&lt;/code>. In the example above, the parent passes an immutable &lt;code>numbers&lt;/code> array, so &lt;code>PureComponent&lt;/code> fits.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Just a handful of notes—call it a mini book report.&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://reactjs.org/docs/react-api.html#reactpurecomponent" target="_blank" rel="noopener">React.PureComponent&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/redux-saga/redux-saga" target="_blank" rel="noopener">redux-saga source&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://wulv.site/2017-05-31/react-purecomponent.html" target="_blank" rel="noopener">React PureComponent usage guide&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.mattzeunert.com/2016/01/28/javascript-deep-equal.html" target="_blank" rel="noopener">JavaScript deep object comparison&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Abandoning Navicat, Switching to DataGrip</title><link>https://en.1991421.cn/2019/10/01/navicat-datagrip/</link><pubDate>Tue, 01 Oct 2019 23:59:47 +0800</pubDate><guid>https://en.1991421.cn/2019/10/01/navicat-datagrip/</guid><description>&lt;blockquote>
&lt;p>For DB tools, I&amp;rsquo;ve been using Navicat, from cracked versions to single DB versions, then to Essentials versions, back and forth. Now I&amp;rsquo;ve decided to switch to JetBrains&amp;rsquo; DataGrip.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-10-02-014747.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="reasons-for-abandoning-navicat">
&lt;a class="heading-anchor-link" href="#reasons-for-abandoning-navicat">Reasons for Abandoning Navicat&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="reasons-for-abandoning-navicat"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Price&lt;/p>
&lt;p>The license is expensive. For single DB versions like MySQL, it costs over 1000 yuan per year, and for the flagship cross-database version, it costs over 5000 yuan per year. At work, I prefer one software to solve one category of problems, just like IDEs - you can&amp;rsquo;t have a specific IDE for each language; having one all-purpose one is better. So I prefer using Navicat&amp;rsquo;s flagship version, but the price is too high for personal purchase. Unfortunately, the company doesn&amp;rsquo;t provide flagship version licenses either [special cases can go through project applications - troublesome].&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Efficiency&lt;/p>
&lt;p>Navicat&amp;rsquo;s GUI is mature and beautiful, but for programmers, mouse operations are still several beats slower. Compared to JetBrains&amp;rsquo; support for shortcuts in IDEA, WebStorm, etc., it&amp;rsquo;s weak.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Slow Updates&lt;/p>
&lt;p>Software updates are slow, and they don&amp;rsquo;t provide SDKs, so personal custom development is impossible. So when you encounter problems, there&amp;rsquo;s nowhere to ask, you can only wait. I remember encountering issues with DB data export to Excel support before.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>After complaining about the shortcomings, of course Navicat isn&amp;rsquo;t without advantages - after all, it&amp;rsquo;s a mature product. Especially the flagship version supports various mainstream databases [relational or non-relational databases], and this alone beats most DB software. Additionally, common functions like import/export, queries, backups are all comprehensive.&lt;/p>
&lt;p>But since it&amp;rsquo;s expensive, using single database versions results in having to switch between different software. Also, cracked or Essential versions aren&amp;rsquo;t long-term solutions, so I decided to switch!&lt;/p>
&lt;h2 id="reasons-for-choosing-datagrip">
&lt;a class="heading-anchor-link" href="#reasons-for-choosing-datagrip">Reasons for Choosing DataGrip&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="reasons-for-choosing-datagrip"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The reason for choosing DataGrip is that while ensuring basic functionality, the above 3 shortcomings don&amp;rsquo;t exist.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Comprehensive Features&lt;/p>
&lt;p>After several years of development, DataGrip has comprehensive basic features. It can compete with Navicat, and also supports multiple DBs [PostgreSQL, MySQL, SQLite, MongoDB &lt;code>newly supported in 2019.3&lt;/code>].&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Price&lt;/p>
&lt;p>The license isn&amp;rsquo;t expensive, about 1000+ yuan per year, which is on par with Navicat&amp;rsquo;s single DB version.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Efficiency&lt;/p>
&lt;p>Shortcut support is excellent - you should know that DataGrip is a JetBrains product, so basic operations follow the same conventions, and the learning curve isn&amp;rsquo;t high for those familiar with the basic interface. There are also customizable shortcut options.&lt;/p>
&lt;p>Recommended official video - &lt;a href="https://www.youtube.com/watch?v=Xb9K8IAdZNg&amp;amp;t=231s" target="_blank" rel="noopener">click here&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Fast Updates
JetBrains IDEs update frequently, which is great. Additionally, SDKs are open, allowing secondary development to solve personalized problems.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="shortcomings">
&lt;a class="heading-anchor-link" href="#shortcomings">Shortcomings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="shortcomings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Update:&lt;/p>
&lt;ul>
&lt;li>&lt;code>2022.3&lt;/code> added Redis support&lt;/li>
&lt;li>&lt;code>2019.3&lt;/code> last version added MongoDB support&lt;/li>
&lt;/ul>
&lt;h4 id="insufficient-nosql-support">Insufficient NoSQL Support&lt;/h4>&lt;p>There&amp;rsquo;s quite a demand for this on the official forum - &lt;a href="https://youtrack.jetbrains.com/issue/DBE-41?_ga=2.263967756.1891671747.1569902179-110805512.1543747110" target="_blank" rel="noopener">No-SQL support&lt;/a>
I personally think it&amp;rsquo;s just a matter of time before this gets resolved. But what to do before it&amp;rsquo;s resolved? Some people have no choice but to install other specialized software to handle these unsupported databases. But having to switch back and forth is annoying.&lt;/p>
&lt;p>If it&amp;rsquo;s a database that&amp;rsquo;s not yet supported, you can try searching for plugins. If that doesn&amp;rsquo;t work, you can develop one yourself - the SDK is quite simple.&lt;/p>
&lt;h2 id="datagrip-learning-resources">
&lt;a class="heading-anchor-link" href="#datagrip-learning-resources">DataGrip Learning Resources&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="datagrip-learning-resources"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/watch?v=Xb9K8IAdZNg" target="_blank" rel="noopener">Youtube&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://blog.jetbrains.com/datagrip/2017/04/20/how-to-find-things-in-datagrip/" target="_blank" rel="noopener">How to Find Things in DataGrip&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Previously, my experience with DB tools was quite frustrating [somewhat troublesome]. This time I made up my mind to switch apps. Next, I need to practice more to improve familiarity and thus boost productivity. I also hope DataGrip will step up, follow public opinion, and quickly support NoSQL databases!&lt;/p></description></item><item><title>MacBook Pro 2015 Model External Dual Monitor Setup</title><link>https://en.1991421.cn/2019/09/26/macbook-pro-2015/</link><pubDate>Thu, 26 Sep 2019 23:15:53 +0800</pubDate><guid>https://en.1991421.cn/2019/09/26/macbook-pro-2015/</guid><description>&lt;blockquote>
&lt;p>My main productivity machine is still the MacBook Pro 2015 15-inch [joined the company at the right time, perfectly catching the last batch of inventory clearance]. At the office, I&amp;rsquo;m limited by equipment, only extending to a Dell 24-inch monitor [slight productivity improvement]. At home, I&amp;rsquo;ve always used &lt;code>Dell U2515H&lt;/code> in extended screen mode. Recently, considering improving happiness, I decided to build an external dual-screen setup, so I purchased &lt;code>Dell U2719DS&lt;/code>.&lt;/p>
&lt;/blockquote>
&lt;p>When tinkering with connecting two external screens, it took some time. Surprisingly, I found very little information about MacBook Pro multi-screen expansion. I&amp;rsquo;ll play the role of Lei Feng (helpful person) and share my rough understanding here.&lt;/p>
&lt;h2 id="ultimate-goal">
&lt;a class="heading-anchor-link" href="#ultimate-goal">Ultimate Goal&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ultimate-goal"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>What I wanted to achieve was a single cable output from the MacBook that could daisy-chain two monitors [note: not mirroring screens, but extending screens].&lt;/p>
&lt;p>&lt;code>Dream&lt;/code> effect as follows:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-09-26-142455.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="mst">
&lt;a class="heading-anchor-link" href="#mst">MST&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mst"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The technology that supported my idea was this:&lt;/p>
&lt;blockquote>
&lt;p>DisplayPort Multi-Stream Transport allows you to use DisplayPort v1.2 for daisy-chaining monitors. &amp;ldquo;Daisy chain&amp;rdquo; refers to the function of connecting a series of devices together using a single connection between two devices. DisplayPort daisy chainable monitors have both DisplayPort input and DisplayPort output. The DisplayPort output connects to the next downstream monitor. This wiring using a single DisplayPort cable between each set of monitors provides a less cluttered system configuration.&lt;/p>
&lt;/blockquote>
&lt;h2 id="macbook-pro-doesnt-support-mst">
&lt;a class="heading-anchor-link" href="#macbook-pro-doesnt-support-mst">MacBook Pro Doesn&amp;rsquo;t Support MST?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="macbook-pro-doesnt-support-mst"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>MacBook does support it, but generally monitor ports are DP ports not Thunderbolt ports, and macOS doesn&amp;rsquo;t support DP cable MST [conclusion from Dell official forum]. To solve it with one cable, you need to purchase Apple&amp;rsquo;s official monitors at a high price.&lt;/p>
&lt;p>If using daisy chaining, my two monitors would be in mirroring relationship, not extended screens.&lt;/p>
&lt;h3 id="luxury-player---apple-official-lg-monitor">
&lt;a class="heading-anchor-link" href="#luxury-player---apple-official-lg-monitor">Luxury Player - Apple Official LG Monitor&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="luxury-player---apple-official-lg-monitor"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>If using the official LG monitor, because it supports Thunderbolt interface, so it can MST connect to MacBook. I understand the second monitor doesn&amp;rsquo;t have to be LG, as long as you solve the daisy chain between monitor 1 and 2, and enable DisplayPort 1.2.&lt;/p>
&lt;h2 id="final-solution">
&lt;a class="heading-anchor-link" href="#final-solution">Final Solution&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-solution"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Because Apple doesn&amp;rsquo;t support DP interface MST as mentioned above, the final solution could only be using two cables from the laptop - mDP and HDMI - outputting to two monitors, achieving dual extended screens. Effect picture below.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-09-26-145109.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="cables-used">
&lt;a class="heading-anchor-link" href="#cables-used">Cables Used&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cables-used"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>mDP &lt;code>Mac end&lt;/code> =&amp;gt; DP &lt;code>monitor end&lt;/code>&lt;/li>
&lt;li>HDMI &lt;code>Mac end&lt;/code> =&amp;gt; DP &lt;code>monitor end&lt;/code>&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>For cable selection, just follow the interface specifications supported by Mac. Since Mac has Thunderbolt port (mDP) and HDMI port, just make sure the monitor side has corresponding cables to connect. HDMI Mac =&amp;gt; any monitor port, MDP to any monitor port.&lt;/p>
&lt;/blockquote>
&lt;h3 id="monitors-used">
&lt;a class="heading-anchor-link" href="#monitors-used">Monitors Used&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="monitors-used"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>Dell U2719DS&lt;/li>
&lt;li>Dell U2515H&lt;/li>
&lt;/ol>
&lt;h2 id="macbook-pro-15-inch-interface-specifications">
&lt;a class="heading-anchor-link" href="#macbook-pro-15-inch-interface-specifications">MacBook Pro 15-inch Interface Specifications&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="macbook-pro-15-inch-interface-specifications"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2022/2022-07-21-191849.jpeg"
alt="https://static.1991421.cn/2022/2022-07-21-191849.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After setting up such a dual-screen configuration, I usually close the laptop and enable clamshell mode, with the left vertical screen for viewing documents and web pages, and the main screen for development. Productivity can be improved a bit more. So, life never stops, tinkering never ends.&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.zhihu.com/question/22600143" target="_blank" rel="noopener">Can Macbook Air Connect to Dual Monitors (Non-Apple Monitors)&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://support.apple.com/kb/SP719?locale=zh_CN&amp;amp;viewlocale=zh_CN" target="_blank" rel="noopener">MacBook Pro (Retina display, 15-inch, Mid 2015) - Technical Specifications&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.dell.com/support/article/hk/zh/hkdhs1/sln293813/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8-displayport-%E5%A4%9A%E6%B5%81%E4%BC%A0%E8%BE%93-mst-%E9%93%BE%E6%8E%A5%E5%88%B0%E5%A4%9A%E5%8F%B0%E6%98%BE%E7%A4%BA%E5%99%A8?lang=zh" target="_blank" rel="noopener">How to Use DisplayPort Multi-Stream Transport (MST) to Link to Multiple Monitors&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.dell.com/community/Monitors/U2518D-Dual-MST-Mac-Pro-only-mirroring/td-p/7278423" target="_blank" rel="noopener">U2518D, Dual MST, Mac Pro, only mirroring&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Creating Email Templates in Apple Mail</title><link>https://en.1991421.cn/2019/09/08/8880f02/</link><pubDate>Sun, 08 Sep 2019 15:32:43 +0800</pubDate><guid>https://en.1991421.cn/2019/09/08/8880f02/</guid><description>&lt;blockquote>
&lt;p>Due to current work requirements, I need to send emails to the organization every week. The sender and content format are fixed, with only specific items differing. Each time I send an email, I either search through previously sent emails and click Forward, then tediously make changes, or look up recipient information in Evernote before adding content. All these approaches are inelegant and not agile or efficient at all！&lt;/p>
&lt;/blockquote>
&lt;p>I definitely need to create an email template. Does Mail support this？ I did some research on Google and found that it is indeed possible. Let&amp;rsquo;s get started.&lt;/p>
&lt;h2 id="creating-email-templates">
&lt;a class="heading-anchor-link" href="#creating-email-templates">Creating Email Templates&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="creating-email-templates"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>Add a new email&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Click the close button, and the email will be stored as a draft in the drafts folder&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Create a folder called Templates under iCloud&lt;/p>
&lt;p>menu =&amp;gt; mailbox =&amp;gt; new Mailbox&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-09-08-072351.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Drag the created draft to the Templates folder&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="how-to-send-an-email-now">
&lt;a class="heading-anchor-link" href="#how-to-send-an-email-now">How to Send an Email Now&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="how-to-send-an-email-now"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Select the template, right-click, and click &amp;ldquo;Send Again&amp;rdquo;&lt;/li>
&lt;li>Add custom content, then click send&lt;/li>
&lt;/ol>
&lt;h2 id="modifying-templates">
&lt;a class="heading-anchor-link" href="#modifying-templates">Modifying Templates&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="modifying-templates"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Templates are stored as emails, so they can&amp;rsquo;t be edited directly. You need to choose &amp;ldquo;Send Again,&amp;rdquo; make modifications, click the X button, and select save. This will save it to the drafts folder by default. Then you need to drag it back into the Templates folder.&lt;/p>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Compared to previous methods, it&amp;rsquo;s not a huge change, but it saves time, which makes me happy！&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://ericleeclark.com/create-email-templates-in-apple-mail-mojave/" target="_blank" rel="noopener">How to Create Email Templates in Apple Mail macOS Mojave&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>My Experience After Two Weeks with the Bose 700</title><link>https://en.1991421.cn/2019/09/04/bose7002/</link><pubDate>Wed, 04 Sep 2019 21:46:15 +0800</pubDate><guid>https://en.1991421.cn/2019/09/04/bose7002/</guid><description>&lt;blockquote>
&lt;p>My recent high-speed train trips and the further deterioration of my work environment have moved me from hesitating about buying noise-canceling headphones to deciding to buy them.
Here are my considerations for the purchase and my feelings after two weeks of use. Since people around me have been asking, I&amp;rsquo;m summarizing my experience.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-09-04-132453.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="why-i-bought-the-bose-700">
&lt;a class="heading-anchor-link" href="#why-i-bought-the-bose-700">Why I Bought the Bose 700&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-i-bought-the-bose-700"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>My colleagues all uniformly bought the Bose QC35 II, &lt;code>to the point where others mistakenly thought our company was giving out headphones&lt;/code>. I had considered this model too, and also tried the WH-1000XM3, but I personally found Sony&amp;rsquo;s uncomfortable and pressing. The comfort of the 35 is truly unmatched.&lt;/p>
&lt;p>After extensive testing and watching review videos, I finally decided to buy the 700. Here&amp;rsquo;s why:&lt;/p>
&lt;ol>
&lt;li>At this stage, JD.com still maintains the QC35 II price at 2299 yuan, while Pinduoduo and Taobao are not trustworthy - there could be issues with invoices and repairs&lt;/li>
&lt;li>Bose recently released the new 700 model, priced at 2999 yuan, and the price difference alone isn&amp;rsquo;t that significant&lt;/li>
&lt;li>One rule of digital products: buy new, not old&lt;/li>
&lt;li>For the Sony WH-1000XM3, I tried them at the electronics store and found them uncomfortable. Some people say they&amp;rsquo;re good, maybe they&amp;rsquo;re just not for me [I had impulsively ordered them before, tried them, and immediately returned them]&lt;/li>
&lt;li>Bose updates slowly - the 35 was from 2017, and they just released something new, so at least I won&amp;rsquo;t feel like I&amp;rsquo;m losing out&lt;/li>
&lt;/ol>
&lt;p>Based on these factors, I purchased the 700.&lt;/p>
&lt;h2 id="usage-feedback">
&lt;a class="heading-anchor-link" href="#usage-feedback">Usage Feedback&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="usage-feedback"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I ordered on August 18th and have been using them for 2 weeks now. Here are the pros and cons.&lt;/p>
&lt;h3 id="advantages">
&lt;a class="heading-anchor-link" href="#advantages">Advantages&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="advantages"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The &lt;code>build quality&lt;/code> is much stronger than before. The previous model felt very plastic, but now the headband has a matte feel, the ear cups are more comfortable than before, and the overall build quality is really excellent&lt;/li>
&lt;li>The &lt;code>touch controls&lt;/code> are good, with gestures consistent with AirPods, so there&amp;rsquo;s no learning curve. Regarding accidental touches, I haven&amp;rsquo;t had any issues with that&lt;/li>
&lt;li>&lt;code>USB-C&lt;/code> port, moving toward more standardization - if you have many USB-C devices, you can carry fewer cables&lt;/li>
&lt;li>The headphone case is also more upscale than before. The larger size isn&amp;rsquo;t an issue for me since I use a backpack&lt;/li>
&lt;li>Excellent noise cancellation, plus support for &lt;code>personalized noise cancellation level settings&lt;/code>&lt;/li>
&lt;li>&lt;code>Call quality&lt;/code> is good&lt;/li>
&lt;li>&lt;code>20-hour battery life&lt;/code> is enough for me&lt;/li>
&lt;/ol>
&lt;h3 id="disadvantages">
&lt;a class="heading-anchor-link" href="#disadvantages">Disadvantages&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="disadvantages"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The new Bose Music app is &lt;code>as terrible as it gets&lt;/code> - it&amp;rsquo;s so bad I don&amp;rsquo;t even want to open it. I feel like Bose needs to hire my company to design and develop it. There&amp;rsquo;s absolutely no user experience. Hopefully, they&amp;rsquo;ll upgrade it soon&lt;/li>
&lt;li>The physical buttons are too small, and I think their placement isn&amp;rsquo;t good. When taking off the headphones, it&amp;rsquo;s particularly easy to press them accidentally&lt;/li>
&lt;/ol>
&lt;h3 id="controversial-issues">
&lt;a class="heading-anchor-link" href="#controversial-issues">Controversial Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="controversial-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Looking online, there are several highly debated issues. Here&amp;rsquo;s my take on them:&lt;/p>
&lt;p>&lt;em>Disclaimer: Everyone&amp;rsquo;s experience may differ, I recommend trying them in a physical store&lt;/em>&lt;/p>
&lt;ol>
&lt;li>Reduced noise cancellation level?
I don&amp;rsquo;t think so. I didn&amp;rsquo;t use the 35 much, just for a day, but I personally feel the noise cancellation has improved. A colleague who has been using the 35 also confirmed an improvement after trying the 700. From Bose&amp;rsquo;s product perspective, it wouldn&amp;rsquo;t make sense to release a new product that&amp;rsquo;s worse than before. So I don&amp;rsquo;t think it has decreased. As for how much it has improved, I think different people will have slightly different perceptions.&lt;/li>
&lt;li>Larger size, less convenient?
Yes, compared to the previous model that could fold, the storage space has definitely increased, to the point where the official headphone case is larger than before. But personally, I don&amp;rsquo;t think it&amp;rsquo;s a problem. At first, it seemed big, but after using it, it&amp;rsquo;s fine. Also, there are advantages to not folding - you can use it right away when you take it out. So I don&amp;rsquo;t consider this issue a real flaw.&lt;/li>
&lt;/ol>
&lt;h2 id="my-daily-usage-scenarios">
&lt;a class="heading-anchor-link" href="#my-daily-usage-scenarios">My Daily Usage Scenarios&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-daily-usage-scenarios"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I primarily use headphones in the following scenarios:&lt;/p>
&lt;ol>
&lt;li>Wearing them in the office to help focus on work&lt;/li>
&lt;li>On commutes, quietly listening to music or reading, which is quite pleasant&lt;/li>
&lt;li>The dreaded high-speed train with all kinds of noise - I haven&amp;rsquo;t taken one since buying these headphones, but I&amp;rsquo;m looking forward to using them during the National Day holiday&lt;/li>
&lt;/ol>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>New designs bring new problems. But the pros outweigh the cons, and what matters is that they work for you. The 700 certainly has flaws, but I personally think it&amp;rsquo;s still better than its predecessor. So, if you&amp;rsquo;re planning to buy Bose, don&amp;rsquo;t hesitate, jump on board now!&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-09-04-134333.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p></description></item><item><title>OOBootcamp Training Insights</title><link>https://en.1991421.cn/2019/08/08/oobootcamp/</link><pubDate>Thu, 08 Aug 2019 21:40:56 +0800</pubDate><guid>https://en.1991421.cn/2019/08/08/oobootcamp/</guid><description>&lt;h2 id="oobootcamp-training-insights">
&lt;a class="heading-anchor-link" href="#oobootcamp-training-insights">OOBootcamp Training Insights&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="oobootcamp-training-insights"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>At the end of April this year, I participated in the company&amp;rsquo;s OOBootcamp training. The training consisted of 6 sessions, and throughout the process, I gained several key insights that I&amp;rsquo;d like to organize here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;em>I should have organized this earlier, but kept procrastinating. After some encouragement from our company&amp;rsquo;s Peiqi, I finally decided to write it down. The muscular guy on the right in the picture below is him&lt;/em>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-08-07-050204.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="repeatedly-confirm-user-requirements">
&lt;a class="heading-anchor-link" href="#repeatedly-confirm-user-requirements">Repeatedly Confirm User Requirements&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="repeatedly-confirm-user-requirements"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>What we create, whether for personal use or commercial products, ultimately faces users. Only when users use it and use it well can it deliver value. Conversely, if it doesn&amp;rsquo;t gain user recognition or deviates from user needs, the value becomes low or zero.&lt;/p>
&lt;p>During the OO training, we worked on parking lot development for 5 sessions [I think]. At the beginning, there was a significant gap between our understanding and the actual user requirements. After hitting several walls, we gradually realized the importance of confirming requirements.&lt;/p>
&lt;h2 id="test-naming">
&lt;a class="heading-anchor-link" href="#test-naming">Test Naming&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="test-naming"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>This insight is probably the one I&amp;rsquo;m most satisfied with. Why? Because it&amp;rsquo;s the most direct. Tests correspond to our confirmed user requirements, using a short sentence to describe a scenario and an expectation.&lt;/p>
&lt;p>After discussion and referencing our company&amp;rsquo;s practices, we settled on the following test case naming convention:&lt;/p>
&lt;p>&lt;code>should_xxxx_when_xxx_given&lt;/code>&lt;/p>
&lt;p>This corresponds to our expectations, execution timing, and given conditions.&lt;/p>
&lt;p>Of course, it&amp;rsquo;s important to highlight one point: &lt;code>If you encounter test names that are too long and cannot be shortened, prioritize readability over brevity - don't shorten just for the sake of shortening.&lt;/code>&lt;/p>
&lt;h2 id="code-simplicity">
&lt;a class="heading-anchor-link" href="#code-simplicity">Code Simplicity&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="code-simplicity"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Throughout the OO training, we focused less on theory and more on hands-on coding. While writing lines of code, we also thought and discussed about how code should be structured and what constitutes good code. One thing we were certain about: code should be simple.&lt;/p>
&lt;p>Our company&amp;rsquo;s Jian once said, &lt;code>&amp;quot;When working on projects or products, the real challenge is making complex things simple.&amp;quot;&lt;/code>&lt;/p>
&lt;p>Let me vent a bit: I worked on a project for over a year that only had 3-4 pages. Can you imagine?&lt;/p>
&lt;p>For example, WeChat - you just click around a few pages. Simple? Baidu search has just one input box. Simple?&lt;/p>
&lt;p>So, for complex matters, we should strive to make them simple. The same goes for code - we abstract, specify, and eventually break down code into simple units. The simpler the program, the better its maintainability and readability.&lt;/p>
&lt;h2 id="benefits-of-tasking">
&lt;a class="heading-anchor-link" href="#benefits-of-tasking">Benefits of Tasking&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="benefits-of-tasking"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I first learned about Tasking when Jian suggested it during pairing. [I mention him again - can&amp;rsquo;t help it, he&amp;rsquo;s excellent]&lt;/p>
&lt;p>Tasking essentially means &lt;code>&amp;quot;breaking down how to put an elephant into a refrigerator into steps&amp;quot;&lt;/code> and then tackling them one by one.&lt;/p>
&lt;p>Currently, I use Things to break down work into tasks and complete them step by step.&lt;/p>
&lt;h3 id="revealing-key-information">
&lt;a class="heading-anchor-link" href="#revealing-key-information">Revealing Key Information&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="revealing-key-information"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>When doing Tasking, we often use a few sentences to organize our thoughts. It&amp;rsquo;s important to highlight that these sentences should reveal key information.&lt;/p>
&lt;h2 id="benefits-of-tdd">
&lt;a class="heading-anchor-link" href="#benefits-of-tdd">Benefits of TDD&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="benefits-of-tdd"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Is TDD good? I&amp;rsquo;d say yes. TDD itself reinforces the importance of testing and, through testing, refines and organizes business points and key aspects. Ultimately, it safeguards the so-called correct logic.&lt;/p>
&lt;p>When we write the three parts of tests [given, when, then], we gradually drive out the actual business code.&lt;/p>
&lt;h3 id="why-write-tests-first">
&lt;a class="heading-anchor-link" href="#why-write-tests-first">Why Write Tests First&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-write-tests-first"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>This is a fundamental question. Writing tests first serves as a double confirmation to some extent. Additionally, tests define the correct inputs and outputs for our business code. So, test-first is correct and wise.&lt;/p>
&lt;p>Currently, much of my code doesn&amp;rsquo;t follow TDD. This is something I need to practice deeply going forward. But there&amp;rsquo;s no denying that testing is necessary, and TDD is beautiful.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Well, that&amp;rsquo;s it - short, maybe superficial, but I&amp;rsquo;m being willful! During the OO training, I had many collisions and exchanges with coaches and colleagues. I remember one session going until after 10 PM - it was tiring but also brilliant. I firmly believe that growth happens through collisions. These insights will be integrated into my understanding and applied in future work and learning.&lt;/p></description></item><item><title>Azure Free Trial for 1 Month</title><link>https://en.1991421.cn/2019/07/07/88194639/</link><pubDate>Sun, 07 Jul 2019 09:56:46 +0800</pubDate><guid>https://en.1991421.cn/2019/07/07/88194639/</guid><description>&lt;blockquote>
&lt;p>Microsoft Azure offers benefits for new users. They provide a $200 credit with a 1-month free period, which is useful for temporary testing or setting up services like a proxy. Here&amp;rsquo;s a summary of the process.&lt;/p>
&lt;/blockquote>
&lt;h2 id="prerequisites">
&lt;a class="heading-anchor-link" href="#prerequisites">Prerequisites&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="prerequisites"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>A &lt;code>Visa dual-currency card&lt;/code> for payment binding&lt;/li>
&lt;li>A good &lt;code>terminal&lt;/code> for deploying SS, such as iterm2 on Mac&lt;/li>
&lt;li>A &lt;code>Microsoft account&lt;/code> - if you don&amp;rsquo;t have one, you&amp;rsquo;ll be prompted to register when logging into Azure&lt;/li>
&lt;li>You might need access to Google&lt;/li>
&lt;/ul>
&lt;h2 id="log-in-to-the-international-azure-website">
&lt;a class="heading-anchor-link" href="#log-in-to-the-international-azure-website">Log in to the International Azure Website&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="log-in-to-the-international-azure-website"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Address: &lt;a href="https://azure.microsoft.com" target="_blank" rel="noopener">https://azure.microsoft.com&lt;/a>&lt;/p>
&lt;p>Follow the steps, and for the bank card section, just fill in the information normally. For the address, you can actually fill in whatever you want.&lt;/p>
&lt;p>&lt;em>Key point&lt;/em>: Just make sure the bank card information is correct&lt;/p>
&lt;h2 id="enter-the-portal">
&lt;a class="heading-anchor-link" href="#enter-the-portal">Enter the Portal&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="enter-the-portal"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After successful registration, click on portal to enter the management page&lt;/p>
&lt;p>&lt;a href="https://portal.azure.com/#home" target="_blank" rel="noopener">https://portal.azure.com/#home&lt;/a>&lt;/p>
&lt;p>The page is quite complex. If you find English difficult, you can switch the language&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-07-07-013433.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>OK, click on the left menu&lt;/p>
&lt;h2 id="create-an-instance">
&lt;a class="heading-anchor-link" href="#create-an-instance">Create an Instance&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="create-an-instance"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;em>Key point&lt;/em>: Choose the lowest configuration because the free $200 credit isn&amp;rsquo;t actually that much money, and Azure is expensive!&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-07-07-013530.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-07-07-013644.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Fill in all the required fields as requested, continue through the steps, and finally click create. If successful, you&amp;rsquo;ll receive a notification.&lt;/p>
&lt;h3 id="ssh-user">
&lt;a class="heading-anchor-link" href="#ssh-user">SSH User&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ssh-user"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>If you chose username and password for SSH, remember to record them, as you&amp;rsquo;ll need them when accessing via terminal&lt;/p>
&lt;h3 id="public-ip">
&lt;a class="heading-anchor-link" href="#public-ip">Public IP&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="public-ip"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-07-07-014608.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>You need to create a new one here, so you&amp;rsquo;ll have a fixed IP for external access&lt;/p>
&lt;h2 id="port-opening">
&lt;a class="heading-anchor-link" href="#port-opening">Port Opening&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="port-opening"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>You need to add SSH port 22 and the future SS service port to the inbound port rules.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-07-07-014309.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="related-links">
&lt;a class="heading-anchor-link" href="#related-links">Related Links&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="related-links"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://zhuanlan.zhihu.com/p/62762581" target="_blank" rel="noopener">Global Lowest Price, Aren&amp;rsquo;t You Going to Get on Board with Indian Region YouTube Premium Membership?&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://blog.yiheng.moe/share/azure.html" target="_blank" rel="noopener">https://blog.yiheng.moe/share/azure.html&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://suniceman.com/2019/04/10/install-shadowsocks-in-one-command/" target="_blank" rel="noopener">One-Click Script to Set Up SS/SSR Service and Enable BBR Acceleration&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Building Smart Home 1.0</title><link>https://en.1991421.cn/2019/06/23/smart-home-setup/</link><pubDate>Sun, 23 Jun 2019 21:57:04 +0800</pubDate><guid>https://en.1991421.cn/2019/06/23/smart-home-setup/</guid><description>&lt;blockquote>
&lt;p>Smart home systems are gradually entering our lives. While the device costs aren&amp;rsquo;t high, the interaction methods and experiences they bring were previously unimaginable. Here I&amp;rsquo;ll document my Smart Home 1.0 setup.&lt;/p>
&lt;/blockquote>
&lt;h2 id="xiao-ai-speaker---smart-hub">
&lt;a class="heading-anchor-link" href="#xiao-ai-speaker---smart-hub">Xiao Ai Speaker - Smart Hub&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xiao-ai-speaker---smart-hub"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I have to say, Xiaomi&amp;rsquo;s smart home ecosystem is very down-to-earth. Since getting the Xiao Ai speaker, all Xiaomi device operations are handled through Xiao Ai. Currently purchased Xiaomi devices include Xiaomi desk lamp, Xiaomi air purifier, Xiaomi router, and Xiaomi universal remote control.&lt;/p>
&lt;p>Turning off the desk lamp and purifier now only requires voice activation: &lt;code>Xiao Ai, turn off the desk lamp&lt;/code>.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-06-23-150043.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="device-pairing-on-24g-network">
&lt;a class="heading-anchor-link" href="#device-pairing-on-24g-network">Device Pairing on 2.4G Network&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="device-pairing-on-24g-network"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>When configuring devices, it&amp;rsquo;s worth noting that Xiaomi devices cannot connect to 5G networks, reportedly because network card components are expensive. There&amp;rsquo;s no way around it given the price point. So to properly connect Xiaomi devices to Mi Home, you need to provide a 2.4G network. Set up Mi Home devices while your phone is on this network, then you can switch your phone to 5G afterward.&lt;/p>
&lt;h3 id="xiaomi-universal-remote-control">
&lt;a class="heading-anchor-link" href="#xiaomi-universal-remote-control">Xiaomi Universal Remote Control&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xiaomi-universal-remote-control"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I accidentally discovered Xiaomi has this amazing device, designed to solve the &lt;code>traditional appliance control problem&lt;/code>. I&amp;rsquo;ve always been carelessly throwing around the air conditioner remote, spending time searching for it every time. Now that&amp;rsquo;s solved. After confirming this was exactly what I needed, I immediately ordered it.&lt;/p>
&lt;p>Through this remote control, traditional appliances like TV and air conditioner are connected to Xiao Ai. From now on, just saying &lt;code>Xiao Ai, turn off the air conditioner&lt;/code> - couldn&amp;rsquo;t be better.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-06-23-150816.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="homepod---music-enthusiast">
&lt;a class="heading-anchor-link" href="#homepod---music-enthusiast">HomePod - Music Enthusiast&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="homepod---music-enthusiast"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As a poor Apple fan, after watching HomePod advertisements and reviews, I couldn&amp;rsquo;t resist and bought one. After using it for a while, my experience can be summarized in two sentences:&lt;/p>
&lt;ul>
&lt;li>Audio quality for this price point: Worth it!&lt;/li>
&lt;li>Intelligence for this price point: Disappointing!&lt;/li>
&lt;/ul>
&lt;p>Siri has been developing for so many years, and I have to say it&amp;rsquo;s still quite poor. Of course, I mainly use HomePod for listening to music, so I&amp;rsquo;ve compromised on the intelligence aspect, hoping new system releases can improve it.&lt;/p>
&lt;p>Apple&amp;rsquo;s closed-loop experience is fantastic. For example, lying in bed and voice-activating HomePod to play music, when you find the volume too loud, besides voice-activating Siri to adjust it, you can directly raise your wrist, scroll the crown, and adjust the volume. This experience is truly amazing!&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-06-23-150539.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="apple-music-subscription">
&lt;a class="heading-anchor-link" href="#apple-music-subscription">Apple Music Subscription&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-music-subscription"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>If you&amp;rsquo;re buying a HomePod, be prepared to subscribe to Apple Music, because HomePod only supports this and doesn&amp;rsquo;t support third-party apps. Of course, Apple Music is quite affordable, and the music library sound quality is good, just not comprehensive.&lt;/li>
&lt;li>If you log out of your current Apple ID and log into Apple Music, you&amp;rsquo;ll find all songs are gone. Awkward and frustrating, isn&amp;rsquo;t it?&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Now there are two souls in my home: one manages music, one manages electrical devices. It&amp;rsquo;s not perfect, but it&amp;rsquo;s quite wonderful. Let&amp;rsquo;s go!&lt;/p></description></item><item><title>Registering a US Apple ID</title><link>https://en.1991421.cn/2019/06/23/appleid/</link><pubDate>Sun, 23 Jun 2019 00:48:11 +0800</pubDate><guid>https://en.1991421.cn/2019/06/23/appleid/</guid><description>&lt;blockquote>
&lt;p>Recently, even with SS running on my phone, I couldn&amp;rsquo;t add a Gmail account to the native Mail app. It would log in successfully but fail to save, and there was no save button. After searching, I found many people reporting this issue. It turns out it&amp;rsquo;s a censorship problem. OK, I give up.&lt;/p>
&lt;/blockquote>
&lt;p>The posts mentioned several methods, which seemed troublesome. Some people said Surge could fix it. I preferred this solution because I&amp;rsquo;ve been using the Mac version and think it&amp;rsquo;s very powerful. So I decided to use this to solve the Gmail account issue on my phone. Then the problem came—I needed to buy the iOS version of Surge. But it&amp;rsquo;s not available in the Chinese App Store. First, I needed a US Apple ID, a US PayPal account, and a dual-currency card. Easy? Not really. But for freedom.&lt;/p>
&lt;p>OK, let&amp;rsquo;s start solving it. Here&amp;rsquo;s my process.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-06-22-aaa.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="update">
&lt;a class="heading-anchor-link" href="#update">Update&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="update"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>US PayPal now has strict verification, and fake US information won&amp;rsquo;t work. Therefore, using a US PayPal account with Apple ID is no longer feasible.&lt;/p>
&lt;h2 id="prerequisites">
&lt;a class="heading-anchor-link" href="#prerequisites">Prerequisites&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="prerequisites"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>A healthy network connection that can access Google, as all services below are outside the Great Firewall. For how to access outside the firewall, you can learn about *** services.&lt;/li>
&lt;li>A dual-currency card, as many foreign services require Visa, and most services still don&amp;rsquo;t support Alipay.&lt;/li>
&lt;/ul>
&lt;h2 id="register-a-gmail-account">
&lt;a class="heading-anchor-link" href="#register-a-gmail-account">Register a Gmail Account&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="register-a-gmail-account"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Oh, I found that if you register with a US IP, you need a US phone number, which is troublesome. So I chose &lt;code>Hong Kong node authentication&lt;/code>. Registration in Hong Kong allows using a mainland Chinese phone number, so registration was successful.&lt;/p>
&lt;h2 id="register-a-us-apple-id">
&lt;a class="heading-anchor-link" href="#register-a-us-apple-id">Register a US Apple ID&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="register-a-us-apple-id"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Note: &lt;code>Switch to a US node to access&lt;/code>. When you reach the payment section, pay attention to the &amp;ldquo;None&amp;rdquo; option—don&amp;rsquo;t change it. For the address information below, refer to: &lt;a href="https://www.fakeaddressgenerator.com/Random_Address/US_Delaware" target="_blank" rel="noopener">https://www.fakeaddressgenerator.com/Random_Address/US_Delaware&lt;/a>&lt;/p>
&lt;p>After successful registration, log in on your phone without any issues.&lt;/p>
&lt;h2 id="tax-exemption">
&lt;a class="heading-anchor-link" href="#tax-exemption">Tax Exemption&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tax-exemption"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;strong>Note: Choose a tax-exempt state address, otherwise there will be tax when paying for app subscriptions&lt;/strong>&lt;/p>
&lt;p>Address example: Anchorage, AK ?&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-01-31-150115.jpeg"
alt="https://static.1991421.cn/2024/2024-01-31-150115.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="bind-us-card-for-payment">
&lt;a class="heading-anchor-link" href="#bind-us-card-for-payment">Bind US Card for Payment&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="bind-us-card-for-payment"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>In addition to gift card recharge, another method is to bind a US card. I recommend using services like NobePay to apply for a virtual US card. After opening the card, go to the App Store on your phone, click your account, click &amp;ldquo;View Apple ID&amp;rdquo;, click &amp;ldquo;Payment&amp;rdquo;, select &amp;ldquo;Add Payment Method&amp;rdquo;, and choose &amp;ldquo;MasterCard&amp;rdquo;.&lt;/li>
&lt;li>US PayPal is not recommended because it involves binding US identity information.&lt;/li>
&lt;/ol>
&lt;p>After binding payment, it will be more convenient to solve paid app subscriptions/purchases.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Some people may ask, is it worth the trouble? For me, it is. Because with a US Apple ID, I can download more apps. You only have access to apps in the Chinese App Store, while I have access to global apps. Because I can download Surge, so I can use Twitter and Facebook, right?&lt;/p>
&lt;p>Solving this problem:&lt;/p>
&lt;ul>
&lt;li>Led to NobePay, a solution for foreign US cards&lt;/li>
&lt;li>Led to dual-currency cards, solving overseas Visa payment issues&lt;/li>
&lt;li>Led to freedom of internet access, solving content restriction issues&lt;/li>
&lt;/ul>
&lt;p>Therefore, sometimes we need to bravely solve these &lt;code>small problems&lt;/code>. Solving these problems will bring significant benefits, which are lasting and wide-ranging, so it&amp;rsquo;s worth it.&lt;/p>
&lt;h2 id="references">
&lt;a class="heading-anchor-link" href="#references">References&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="references"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://zhuanlan.zhihu.com/p/63398847" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/63398847&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.fakeaddressgenerator.com/Random_Address/US_Delaware" target="_blank" rel="noopener">https://www.fakeaddressgenerator.com/Random_Address/US_Delaware&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.v2ex.com/t/323605" target="_blank" rel="noopener">https://www.v2ex.com/t/323605&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://apple.stackovernet.com/cn/q/66103" target="_blank" rel="noopener">https://apple.stackovernet.com/cn/q/66103&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Getting the NAS DS218j</title><link>https://en.1991421.cn/2019/04/06/nas-ds218j/</link><pubDate>Sat, 06 Apr 2019 12:28:34 +0800</pubDate><guid>https://en.1991421.cn/2019/04/06/nas-ds218j/</guid><description>&lt;blockquote>
&lt;p>My Mac suddenly refused to accept the login password and I couldn&amp;rsquo;t get in. It was a nightmare because all my important files were on it. Apple&amp;rsquo;s support suggested reinstalling the system, but what about my data? That was the moment I realized how risky it is not to have a proper backup.&lt;/p>
&lt;p>If I had a backup, there&amp;rsquo;d be nothing to worry about. Luckily, I eventually got back into the system without any data loss, but the experience taught me a lesson: backups are essential, especially for work machines. They can save you from the massive pain of rebuilding everything.&lt;/p>
&lt;p>So I started thinking about a backup strategy. The two typical options are: 1) plug in an external drive, or 2) back up over the local network with something like a NAS. After weighing the options, NAS felt like the most cost-effective and flexible solution. Plus, a friend had already recommended it, so I decided to dive in.&lt;/p>
&lt;/blockquote>
&lt;h2 id="picking-a-model">
&lt;a class="heading-anchor-link" href="#picking-a-model">Picking a Model&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="picking-a-model"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Once I committed to buying a NAS, the next question was which brand and model. A bit of research showed that Synology gets great reviews—people even joke that buying Synology is like &amp;ldquo;paying for the software and getting the hardware for free.&amp;rdquo; That sold me. As for the model, it mostly comes down to budget. For beginners, the DS218j is a solid choice: dual-bay, 512 MB of RAM, about 1,299 CNY for the bare unit. Add a 2 TB Western Digital Red drive for 549 CNY and you&amp;rsquo;re at roughly 1,800 CNY total. Not bad.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-04-06-IMG_0370.JPG"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>It takes just a few minutes to get up and running, and the initial setup is quite straightforward. Here are the services I use the most.&lt;/p>
&lt;h2 id="time-machine">
&lt;a class="heading-anchor-link" href="#time-machine">Time Machine&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="time-machine"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>For the setup guide, see the official tutorial: &lt;a href="https://www.synology.com/zh-cn/knowledgebase/DSM/tutorial/Backup/How_to_back_up_files_from_Mac_to_Synology_NAS_with_Time_Machine#t1" target="_blank" rel="noopener">How to back up files from Mac to Synology NAS with Time Machine&lt;/a>&lt;/p>
&lt;p>The end result is that every hour, my Mac runs a backup automatically when I&amp;rsquo;m at home. &lt;code>My mom no longer has to worry about my Mac acting up&lt;/code>—even system upgrades are safer because I can always roll back.&lt;/p>
&lt;p>&lt;code>Note that this backup runs over the local network.&lt;/code>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-04-06-040811.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="map-shared-folders-to-your-computer">
&lt;a class="heading-anchor-link" href="#map-shared-folders-to-your-computer">Map Shared Folders to Your Computer&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="map-shared-folders-to-your-computer"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>You could log into the NAS to watch downloaded movies, but the most convenient approach is to map the shared folder as a drive and access everything directly from your computer.&lt;/p>
&lt;p>For instructions, &lt;a href="https://www.synology.com/zh-cn/knowledgebase/DSM/tutorial/File_Sharing/How_to_map_network_drives_from_your_Synology_NAS" target="_blank" rel="noopener">click here&lt;/a>&lt;/p>
&lt;h2 id="webdav-server">
&lt;a class="heading-anchor-link" href="#webdav-server">WebDAV Server&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="webdav-server"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Install and enable WebDAV so that apps like Infuse can access your downloaded media. You can also use SMB, but I chose WebDAV so I can reach the NAS from outside my home network.&lt;/p>
&lt;h2 id="quickconnect">
&lt;a class="heading-anchor-link" href="#quickconnect">QuickConnect&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="quickconnect"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>How do you access the NAS remotely? Synology offers QuickConnect and DDNS.&lt;/p>
&lt;ul>
&lt;li>QuickConnect: Open Control Panel, find QuickConnect, and register. If your QuickConnect ID is &lt;code>xxx&lt;/code>, then &lt;code>http://xxx.quickconnect.cn&lt;/code> will reach your NAS when you&amp;rsquo;re away from home.&lt;/li>
&lt;li>DDNS: You need a public IP from your ISP and port forwarding configured on your router.&lt;/li>
&lt;/ul>
&lt;p>With these two options, remote access is easy. In practice, performance is perfectly acceptable.&lt;/p>
&lt;h2 id="handy-apps">
&lt;a class="heading-anchor-link" href="#handy-apps">Handy Apps&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="handy-apps"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="synology-photos">
&lt;a class="heading-anchor-link" href="#synology-photos">Synology Photos&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="synology-photos"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Install the DS Photos client on devices like Apple TV to browse your photo library.&lt;/p>
&lt;h3 id="download-station--the-ultimate-downloader">
&lt;a class="heading-anchor-link" href="#download-station--the-ultimate-downloader">Download Station – the ultimate downloader&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="download-station--the-ultimate-downloader"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Using the NAS for downloads is fantastic. I used to leave my laptop or desktop running all night to grab files, and sometimes I had to delete favorites because of limited space. Now I just log into the NAS, start the download, and later I can stream or copy the files directly from the NAS. High quality, no ads—bliss.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-04-06-041142.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>When you&amp;rsquo;re browsing the web, just right-click magnet or torrent links to add them.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>There&amp;rsquo;s still so much more you can do with a NAS—host websites, run a private cloud office suite, and more. I&amp;rsquo;ll keep exploring.&lt;/p></description></item><item><title>2018 Year-End Summary</title><link>https://en.1991421.cn/2019/03/09/2018/</link><pubDate>Sat, 09 Mar 2019 23:15:38 +0800</pubDate><guid>https://en.1991421.cn/2019/03/09/2018/</guid><description>&lt;blockquote>
&lt;p>Footprints in the snow. Looking back on 2018, it&amp;rsquo;s time to reflect and summarize.
I feel ashamed. I should have written this at the turn of the year, but now it&amp;rsquo;s already March. Pinch myself, blame myself, and promise not to repeat this.&lt;/p>
&lt;/blockquote>
&lt;h2 id="first-half">
&lt;a class="heading-anchor-link" href="#first-half">First half&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="first-half"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>From February to May, I focused on Project A, which brought new challenges. Role-wise, I shifted from frontend team lead and main developer to first-time project manager. Technically, I moved from pure frontend to overall project tech stack ownership.&lt;/p>
&lt;p>The project was tight on time and heavy on tasks.&lt;/p>
&lt;p>The product already existed in the company, so in theory we could just retrofit the old project. But on one hand, the client had personalized needs, like deeper and more precise data requirements, which forced the data team to work harder. More importantly, the existing tech stack was old and not abstract enough. If we just copied the old stuff, what about stability and flexibility? If another Project B came, could the company deliver with high efficiency and quality? So I decided to push the overall tech forward and pay back years of tech debt.&lt;/p>
&lt;p>Impulse has consequences. I ran into several pits during the push.&lt;/p>
&lt;h3 id="pitfall-1">
&lt;a class="heading-anchor-link" href="#pitfall-1">Pitfall 1&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pitfall-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The old framework version was too low, so when issues came up there was no documentation. That would cause more problems later. I decided to upgrade, but upgrading is not just changing a version number. It comes with issues. Luckily, my hard-won experience with &amp;ldquo;Angular version upgrades&amp;rdquo; came in handy. I bootstrapped a new project with the target version and used an additive migration approach. It worked in the end, but upgrading was definitely not easy.&lt;/p>
&lt;h3 id="pitfall-2">
&lt;a class="heading-anchor-link" href="#pitfall-2">Pitfall 2&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pitfall-2"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Some modules were built in .NET and were not cross-platform, so the host had to be Windows. That meant deployment servers needed licenses, which cost money. We had many distributed crawlers, so costs added up quickly. We couldn&amp;rsquo;t move everything to Linux at once, but we used Linux where we could. This taught me the importance of cross-platform tech. Even from cost alone, you can see it. All those avoidable expenses were losses for both the company and the client.&lt;/p>
&lt;h3 id="pitfall-3">
&lt;a class="heading-anchor-link" href="#pitfall-3">Pitfall 3&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pitfall-3"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Although I was titled XXX manager, the real challenge was whether I could drive every team member. I negotiated an incentive system with the boss to boost team motivation. It helped somewhat, but it was still very hard and exhausting.&lt;/p>
&lt;h2 id="changing-companies">
&lt;a class="heading-anchor-link" href="#changing-companies">Changing companies&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="changing-companies"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Project A ran until mid-year and was close to wrapping up. I felt lighter, but looking back at months of R&amp;amp;D, I felt the returns were small. I was sure the input and output were not favorable, and that was true for the company too.&lt;/p>
&lt;p>Busy and unaware, I had been at the company for 4 years. I complained a lot, pushed a lot, and still couldn&amp;rsquo;t change much. After talking with friends, I realized I might have been in a blind spot - I had not repeatedly confirmed whether my current state was healthy. Yes, I had grown a bit in 4 years, but compared to others, I felt inferior.&lt;/p>
&lt;p>After weeks of thinking, I concluded I didn&amp;rsquo;t match the company. I emailed my leader. He tried to persuade me, but my mind was made up. After more than a month of handover, I left the company I had fought for. It became a chapter in my career history.&lt;/p>
&lt;hr>
&lt;p>I gained freedom, but the pressure didn&amp;rsquo;t lighten. After staying home, I started looking for a new job. It took three weeks, and I found a new company. Finally, I could breathe.&lt;/p>
&lt;h2 id="trip-to-hong-kong-macao-and-taiwan">
&lt;a class="heading-anchor-link" href="#trip-to-hong-kong-macao-and-taiwan">Trip to Hong Kong, Macao, and Taiwan&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="trip-to-hong-kong-macao-and-taiwan"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Because my onboarding time was flexible, I took the offer and gave myself a short vacation. I booked a ticket and went to Shenzhen and Hong Kong/Macao/Taiwan. Going out to experience other lives made me realize that the past few years were a self-made trap. I used to see company problems and push suggestions, then get angry. Now I realize that if you see many things you can&amp;rsquo;t stand and you can&amp;rsquo;t change them, it means you don&amp;rsquo;t fit the company. Leaving is the answer.&lt;/p>
&lt;p>Half a year later, I am even more convinced that leaving decisively was right. Let the right people be in the right company. That is right.&lt;/p>
&lt;h2 id="second-half">
&lt;a class="heading-anchor-link" href="#second-half">Second half&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="second-half"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After the vacation, I started work. As the saying goes, &lt;code>take the money and solve the problems (just kidding)&lt;/code> - time to work.&lt;/p>
&lt;p>I joined the new company in August. It was still challenging, but challenges help you grow.&lt;/p>
&lt;p>In the second half, I took over two projects, Project B and Project C. Due to staffing changes, I only worked on B for two months before being assigned to C. Project C has been ongoing and not finished yet, and I&amp;rsquo;ve heard it will continue into mid-2019. Haha. Productized projects - what can you do.&lt;/p>
&lt;h2 id="outside-of-work">
&lt;a class="heading-anchor-link" href="#outside-of-work">Outside of work&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="outside-of-work"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Besides work changes and experiences, there were other collisions and gains this year.&lt;/p>
&lt;h3 id="tools">
&lt;a class="heading-anchor-link" href="#tools">Tools&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="tools"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I bought several hardware and software tools this year (AirPods, Filco87, AWS4, etc.), which helped my work and life. As the old saying goes, to do a good job, you must first sharpen your tools. Tools are worth investing in and refining.&lt;/p>
&lt;ul>
&lt;li>For details, see &lt;a href="https://1991421.cn/2018/12/09/1db46db9/" target="_blank" rel="noopener">here&lt;/a> - highly recommended.&lt;/li>
&lt;/ul>
&lt;h3 id="xianyu">
&lt;a class="heading-anchor-link" href="#xianyu">Xianyu&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="xianyu"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>This year, I tried using Xianyu to sell some idle gadgets, then used the depreciated money to buy new tools. Over time I formed a habit: sell what I don&amp;rsquo;t want on Xianyu, add some money, and buy stronger tools. Buyers get good devices at low prices, and I upgrade my tools. A win-win, rationally.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>2018 ended. In the new year, I hope to improve my skills faster and become a real programmer before age 30.&lt;/li>
&lt;li>While I grow up, my parents and family are also getting older. In the new year, spend more time with family. In today&amp;rsquo;s fast-paced work life, we often ignore the people we should accompany the most.&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-03-09-151252.png"
alt="2018 Year-End Summary - Fig 1"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p></description></item><item><title>An Awkward No-Network Experience on My Phone</title><link>https://en.1991421.cn/2019/02/05/mobile-network-failure-experience/</link><pubDate>Tue, 05 Feb 2019 15:08:31 +0800</pubDate><guid>https://en.1991421.cn/2019/02/05/mobile-network-failure-experience/</guid><description>&lt;blockquote>
&lt;p>Lunar New Year means heading home. Consider this the first post of the holiday.&lt;/p>
&lt;/blockquote>
&lt;p>Back in my hometown—a small county—you see QR codes everywhere. Mobile payments have finally become mainstream. Convenience and risk always travel together, and I now head out without cash. Cue the embarrassment: I went out for snacks, ready to pay with Alipay, only to notice my phone stuck on &lt;strong>E&lt;/strong> (2.5G) instead of 4G. The vendor had already finished preparing the food, but no payment means no food. I grabbed the shop’s QR code, walked outside, and still had no data. Toggling airplane mode didn’t help. After a reboot, the signal returned, I scanned the code, and the payment went through. Still, that kind of flaky signal makes mobile payments stressful.&lt;/p>
&lt;p>Because rebooting temporarily restored data, I blamed the signal. But during other outings my mom—also on China Unicom—had no issues. Same carrier, different phone. That had to be a clue.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-02-05-IMG_1390.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;em>My suspicion shifted from weak coverage to a device issue.&lt;/em>&lt;/p>
&lt;p>The next morning the network died again. Sometimes even the &lt;strong>E&lt;/strong> icon disappeared, yet the signal bars were full. Imagine not being able to send a WeChat message unless you’re on Wi-Fi—frustrating. While venting to a friend (initially blaming the iPhone), he suggested resetting the iPhone’s network settings. I followed the &lt;a href="https://github.com/alanhe421/mac-question/issues/31" target="_blank" rel="noopener">steps&lt;/a>, but nothing changed.&lt;/p>
&lt;p>His next tip: call customer support. He’d seen similar issues before caused by VPN usage; the carrier had restricted network access until support manually refreshed things.&lt;/p>
&lt;p>So I called. The agent said they’d switch my network profile on the backend and asked me to reboot ten minutes later. It worked immediately. To confirm, I went for a walk—solid 4G the entire time.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2019-02-05-IMG_1389.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>In hindsight, my earlier assumption was wrong. &lt;em>If the signal bars are full but there’s no data, it’s not a coverage problem.&lt;/em> It’s either the phone’s network configuration or the carrier’s provisioning.&lt;/p>
&lt;p>Why was I throttled in the first place? Maybe the VPN, maybe searching for something the system didn’t like—no idea. With millions of users, automated rules inevitably create false positives.&lt;/p>
&lt;p>If you hit the same issue, call support. Let them reset things from their end.&lt;/p></description></item><item><title>Tools I Bought in 2018</title><link>https://en.1991421.cn/2018/12/09/2018/</link><pubDate>Sun, 09 Dec 2018 21:31:26 +0800</pubDate><guid>https://en.1991421.cn/2018/12/09/2018/</guid><description>&lt;blockquote>
&lt;p>Tools need refinement and periodic upgrades. As 2018 ended, I reviewed the tools I bought and adjusted this year (both hardware and software), organized current capabilities, and highlighted the improvements from those adjustments.&lt;/p>
&lt;p>While documenting, I hope it can help fellow enthusiasts.&lt;/p>
&lt;/blockquote>
&lt;h2 id="filco-87-wireless-second-gen">
&lt;a class="heading-anchor-link" href="#filco-87-wireless-second-gen">Filco 87 Wireless (Second Gen)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="filco-87-wireless-second-gen"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;code>2018.11&lt;/code> purchase, price &lt;code>1104 CNY&lt;/code>. I had been using Filco 67. After seeing a colleague&amp;rsquo;s fluent keyboard flow, I hesitated, since I had always been awkward with shortcuts.&lt;/p>
&lt;p>The difference between 67 and 87 is the key count. Essential function keys for development require chorded keys on 67, which hurts efficiency. The size and weight advantages are not that important for development. After some thought, I decided to switch.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-12-09-IMG_1232.JPG"
alt="Tools I Bought in 2018 - Fig 1"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="features">
&lt;a class="heading-anchor-link" href="#features">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Smooth keyboard flow&lt;/li>
&lt;li>Wireless: Filco&amp;rsquo;s wireless battery life and responsiveness are great, and wireless is convenient.&lt;/li>
&lt;li>Multi-device switching&lt;/li>
&lt;/ul>
&lt;h3 id="improvements">
&lt;a class="heading-anchor-link" href="#improvements">Improvements&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="improvements"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Key remapping with &lt;a href="https://pqrs.org/osx/karabiner/" target="_blank" rel="noopener">Karabiner&lt;/a>
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-12-09-130930.png"
alt="Tools I Bought in 2018 - Fig 2"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/li>
&lt;li>&lt;a href="https://github.com/alanhe421/mac-question/issues/19" target="_blank" rel="noopener">Use Mac media keys as function keys by default&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="airpods">
&lt;a class="heading-anchor-link" href="#airpods">AirPods&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="airpods"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;code>2018.1&lt;/code> purchase, price &lt;code>1248 CNY&lt;/code>. I bought them in January and no regrets - probably my best purchase of the year. I already wrote about them before - &lt;a href="https://1991421.cn/2018/04/22/a73d3c69/" target="_blank" rel="noopener">click here&lt;/a>.&lt;/p>
&lt;h3 id="features-1">
&lt;a class="heading-anchor-link" href="#features-1">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Wireless music&lt;/li>
&lt;li>Calls&lt;/li>
&lt;li>Siri&lt;/li>
&lt;/ul>
&lt;h2 id="apple-watch-series-4">
&lt;a class="heading-anchor-link" href="#apple-watch-series-4">Apple Watch Series 4&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apple-watch-series-4"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;code>2018.11&lt;/code> purchase. AW4 was hot this year. Media reviews were high, comparing it to the iPhone 4 era, and it sold out on JD.com. I hesitated for a long time and then ordered. I bought the 44mm model. See &lt;a href="https://support.apple.com/kb/SP778?locale=zh_CN&amp;amp;viewlocale=zh_CN" target="_blank" rel="noopener">official specs&lt;/a>.&lt;/p>
&lt;p>After browsing Zhihu and asking friends, I tuned the AW to its first stage, saving some time and improving some efficiency.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-12-09-133812.png"
alt="Tools I Bought in 2018 - Fig 3"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h3 id="features-2">
&lt;a class="heading-anchor-link" href="#features-2">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features-2"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Traditional watch functions: time, decoration&lt;/li>
&lt;li>Fitness tracking&lt;/li>
&lt;li>Basic body metrics&lt;/li>
&lt;li>iPhone/AirPods integration, music volume control&lt;/li>
&lt;/ul>
&lt;h3 id="improvements-1">
&lt;a class="heading-anchor-link" href="#improvements-1">Improvements&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="improvements-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Unlock Mac (often used in clamshell mode)&lt;/li>
&lt;li>Find phone&lt;/li>
&lt;/ul>
&lt;h2 id="vimium-chrome-extension">
&lt;a class="heading-anchor-link" href="#vimium-chrome-extension">Vimium (Chrome extension)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="vimium-chrome-extension"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;code>2018.11&lt;/code>&lt;/p>
&lt;blockquote>
&lt;p>Recommended by a friend. It has been popular for years and I didn&amp;rsquo;t even know about it - embarrassing. Strongly recommended.&lt;/p>
&lt;/blockquote>
&lt;h3 id="features-3">
&lt;a class="heading-anchor-link" href="#features-3">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features-3"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Scroll pages with keys, much faster than the mouse wheel&lt;/li>
&lt;li>Jump navigation&lt;/li>
&lt;/ul>
&lt;p>Download: &lt;a href="https://github.com/philc/vimium" target="_blank" rel="noopener">click here&lt;/a>&lt;/p>
&lt;h2 id="reminder-apple-system-app">
&lt;a class="heading-anchor-link" href="#reminder-apple-system-app">Reminder (Apple system app)&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="reminder-apple-system-app"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;code>2018.9&lt;/code> purchase. I used TickTick for tasks before, but it never felt as ingrained as Evernote. I later realized the built-in app is already good and enough for task reminders.&lt;/p>
&lt;h3 id="features-4">
&lt;a class="heading-anchor-link" href="#features-4">Features&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="features-4"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ul>
&lt;li>Use Siri to add tasks&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>A year passes quickly. Life needs work and learning, and life is also a game. Tools are great assistants. Fighting!&lt;/p></description></item><item><title>Filco Minila Air Mechanical Keyboard Setup</title><link>https://en.1991421.cn/2018/10/27/filco-minila-air/</link><pubDate>Sat, 27 Oct 2018 15:46:16 +0800</pubDate><guid>https://en.1991421.cn/2018/10/27/filco-minila-air/</guid><description>&lt;blockquote>
&lt;p>This keyboard has 67 keys, which creates some differences when using it with a Mac. To maintain a consistent operation experience, some settings need to be configured. I found there isn&amp;rsquo;t much information about this online, so I&amp;rsquo;m documenting it here.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2025/2025-05-28-120540.jpeg"
alt="https://static.1991421.cn/2025/2025-05-28-120540.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="preparation">
&lt;a class="heading-anchor-link" href="#preparation">Preparation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="preparation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Install &lt;a href="https://pqrs.org/osx/karabiner/" target="_blank" rel="noopener">Karabiner&lt;/a>&lt;/li>
&lt;li>Keycap puller&lt;/li>
&lt;/ul>
&lt;h2 id="cmd-and-option-key-swap">
&lt;a class="heading-anchor-link" href="#cmd-and-option-key-swap">CMD and Option Key Swap&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cmd-and-option-key-swap"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-10-27-072644.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>
On Mac keyboards, the Control key is to the left of the Option key, so we need to use a keycap puller to swap their positions, and also set key mapping in Karabiner. Note to select the target keyboard in &lt;code>Target Device&lt;/code>.&lt;/p>
&lt;h2 id="fn-function-key-settings">
&lt;a class="heading-anchor-link" href="#fn-function-key-settings">Fn Function Key Settings&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="fn-function-key-settings"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-10-27-072702.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>On Mac, F1-F12 keys are set as media keys by default. To use function keys, you need to press Fn. On the Filco keyboard, we already have one less row of keys, so by default you need to press Fn + number keys to access media keys, which means we can&amp;rsquo;t use function keys normally.&lt;/p>
&lt;p>Since media keys are used less frequently, I set these F keys as function keys so that development shortcut combinations work normally. For example, Rename and Debug functions in IDEA now work properly.&lt;/p>
&lt;h2 id="right-fn-key-set-as-spacebar">
&lt;a class="heading-anchor-link" href="#right-fn-key-set-as-spacebar">Right Fn Key Set as Spacebar&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="right-fn-key-set-as-spacebar"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-10-27-073235.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>
This setting isn&amp;rsquo;t crucial, but since I don&amp;rsquo;t use the right Fn key anyway, it&amp;rsquo;s better to extend the spacebar.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Fine-tuning your keyboard to make it more comfortable is worth the effort to achieve smooth keyboard workflow. Also, Filco keyboards are worth having - they&amp;rsquo;re not actually that expensive.&lt;/li>
&lt;li>When deciding between 67-key and 87-key layouts, think carefully. If you&amp;rsquo;re unsure, go with 87 keys. The 67-key layout inevitably requires many key combinations.&lt;/li>
&lt;/ol></description></item><item><title>Puppy Vacuum D531 — First Impressions</title><link>https://en.1991421.cn/2018/10/14/using-xiaogou/</link><pubDate>Sun, 14 Oct 2018 23:14:06 +0800</pubDate><guid>https://en.1991421.cn/2018/10/14/using-xiaogou/</guid><description>&lt;blockquote>
&lt;p>Hair and dust on the floor are annoying to sweep every day, so I decided to buy a vacuum. Dyson looks great but is pricey (~¥3000+). Since I’m renting and space is limited, I lowered the budget and chose the internet brand Puppy.&lt;/p>
&lt;/blockquote>
&lt;p>I bought the D-531 for &lt;code>¥949&lt;/code>. The screenshot price is just for reference—JD pricing can change daily. Time your purchase.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-10-14-144620.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>After some use, it’s fair to say it’s usable — for ~¥1000, expectations should match the price. Pros and cons below.&lt;/p>
&lt;h2 id="pros">
&lt;a class="heading-anchor-link" href="#pros">Pros&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="pros"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Reasonable price; great if you don’t want to splurge.&lt;/li>
&lt;li>Battery life is fine—roughly 30 minutes.&lt;/li>
&lt;li>Removable battery makes replacements easier than an integrated pack.&lt;/li>
&lt;li>Accessories are decent, including a mite-removal kit.&lt;/li>
&lt;/ol>
&lt;h2 id="cons">
&lt;a class="heading-anchor-link" href="#cons">Cons&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="cons"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Clone-level design—hard to believe it isn’t copying Dyson. Given the market, investing in original design would be costly; early Xiaomi had the same approach.&lt;/li>
&lt;li>Average suction. Exterior design is easy to imitate, but internal engineering is harder, and the big price gap versus Dyson shows. Some debris needs multiple passes, though overall it’s acceptable.&lt;/li>
&lt;li>“One-button dust dump”? Not really. Hair wraps around the bin and won’t fall out. The included brush barely helps; I often shake the bin or pull debris out by hand.&lt;/li>
&lt;/ol>
&lt;h2 id="update">
&lt;a class="heading-anchor-link" href="#update">Update&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="update"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="replacing-the-floor-brush">
&lt;a class="heading-anchor-link" href="#replacing-the-floor-brush">Replacing the Floor Brush&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="replacing-the-floor-brush"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;img src="https://static.1991421.cn/2021/2021-09-29-181243.jpeg" style="zoom: 50%;" />
&lt;p>At first I didn’t know the component names, so I couldn’t find replacements. The manual revealed it’s called the “electric floor brush,” so I ordered one on Pinduoduo for &lt;code>¥140&lt;/code> and swapped it in.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>At this price, it’s basic and has rough edges — ads promise more than it delivers. Puppy’s trajectory reminds me of early Xiaomi: internet‑first, lower price, decent specs, derivative design. If you want a budget vacuum that works, this is fine. You get what you pay for.&lt;/p></description></item><item><title>Export Nintendo Switch Screenshots</title><link>https://en.1991421.cn/2018/10/04/switch/</link><pubDate>Thu, 04 Oct 2018 12:15:32 +0800</pubDate><guid>https://en.1991421.cn/2018/10/04/switch/</guid><description>&lt;blockquote>
&lt;p>I’m still on a first-gen Switch. I wanted an easy way to export game screenshots, so I tried a couple of approaches.&lt;/p>
&lt;/blockquote>
&lt;p>Options:&lt;/p>
&lt;ol>
&lt;li>Copy files from the microSD card.&lt;/li>
&lt;li>Share to Twitter and use &lt;a href="https://ifttt.com/" target="_blank" rel="noopener">IFTTT&lt;/a> to sync shots to the iOS Photos app automatically.&lt;/li>
&lt;/ol>
&lt;p>Method 1 requires ejecting the card, connecting it to a computer, dragging files—tedious and “anti-engineer.” I prefer method 2.&lt;/p>
&lt;h2 id="solve-the-network-constraints-first">
&lt;a class="heading-anchor-link" href="#solve-the-network-constraints-first">Solve the Network Constraints First&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="solve-the-network-constraints-first"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The Switch needs working access to Twitter. Two approaches:&lt;/p>
&lt;ol>
&lt;li>Configure proxy/network on the Switch itself.&lt;/li>
&lt;li>Provide the necessary network environment at home (router/gateway).&lt;/li>
&lt;/ol>
&lt;p>I chose option 2.&lt;/p>
&lt;h2 id="use-ifttt">
&lt;a class="heading-anchor-link" href="#use-ifttt">Use IFTTT&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="use-ifttt"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>IFTTT automates the Twitter → Photos workflow.&lt;/p>
&lt;ol>
&lt;li>Create an IFTTT account.&lt;/li>
&lt;li>Configure an applet (Twitter trigger → Photos action).&lt;/li>
&lt;li>Install the IFTTT app on iPhone (available in the Chinese App Store).&lt;/li>
&lt;li>Link the Switch to your Twitter account.&lt;/li>
&lt;li>Post a tweet; check Photos and the shot should appear.&lt;/li>
&lt;/ol>
&lt;p>Applet configuration example:
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-10-04-ifttt.com_applets_86419437d-if-new-tweet-by-alanhe421-with-hashtag-nintendoswitch-then-add-photo-to-album_edit.png"
alt="https://static.1991421.cn/2018-10-04-ifttt.com_applets_86419437d-if-new-tweet-by-alanhe421-with-hashtag-nintendoswitch-then-add-photo-to-album_edit.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>IFTTT activity log:
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-10-04-041122.png"
alt="https://static.1991421.cn/2018-10-04-041122.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="common-questions">
&lt;a class="heading-anchor-link" href="#common-questions">Common Questions&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="common-questions"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Update the linked Twitter account here: &lt;a href="https://ifttt.com/twitter/settings" target="_blank" rel="noopener">https://ifttt.com/twitter/settings&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Now all I do is tweet from the Switch; the screenshot lands in Photos automatically. Even the long-idle Echo Dot has a job again.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2018-10-04-041833.png"
alt="https://static.1991421.cn/2018-10-04-041833.png"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p></description></item><item><title>As a programmer, here are my thought</title><link>https://en.1991421.cn/2018/05/13/my-reflections-as-programmer/</link><pubDate>Sun, 13 May 2018 22:58:17 +0800</pubDate><guid>https://en.1991421.cn/2018/05/13/my-reflections-as-programmer/</guid><description>&lt;blockquote>
&lt;p>Recently, I have gotten into the habit of setting aside work during weekends and after hours to read fundamental books, read articles, and reflect.&lt;/p>
&lt;p>Looking back on my four years of development, I have the following insights.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/2024/2024-07-27-154657.jpeg"
alt="https://static.1991421.cn/2024/2024-07-27-154657.jpeg"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Know the whole picture, and work on the details.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Open every pore to absorb external knowledge.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>There is always a reason for popularity; stay open-minded.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>At work, if you don&amp;rsquo;t progress, you regress.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Official documentation is the primary source; chew it thoroughly.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="at-the-end">
&lt;a class="heading-anchor-link" href="#at-the-end">At the end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="at-the-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As Lao Luo said, &amp;ldquo;Life goes on; the hustle never stops.&amp;rdquo; Keep pushing forward.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-05-13-151914.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;div class="highlight" index="0">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>PhantomJS Installation</title><link>https://en.1991421.cn/2018/05/01/phantomjs/</link><pubDate>Tue, 01 May 2018 18:32:15 +0800</pubDate><guid>https://en.1991421.cn/2018/05/01/phantomjs/</guid><description>&lt;blockquote>
&lt;p>&lt;a href="https://en.wikipedia.org/wiki/PhantomJS" target="_blank" rel="noopener">PhantomJS&lt;/a> is a WebKit-based JavaScript API. It uses QtWebKit as its core browser functionality and WebKit to compile and execute JavaScript code. It can do anything you can do in a WebKit-based browser, such as server-side generation of JS chart images, with a wide range of application scenarios.&lt;/p>
&lt;/blockquote>
&lt;p>Here&amp;rsquo;s a brief explanation of how to install it.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-05-01-103648.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="linux">
&lt;a class="heading-anchor-link" href="#linux">Linux&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="linux"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ yum install -y bzip2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ bzip2 -d phantomjs-2.1.1-linux-x86_64.tar.bz2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ tar xvf phantomjs-2.1.1-linux-x86_64.tar
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ mv -r phantomjs-2.1.1-linux-x86_64 /usr/local/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ &lt;span class="nb">cd&lt;/span> /usr/local/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ mv phantomjs-2.1.1-linux-x86_64/ phantomjs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ ln -s /usr/local/phantomjs/bin/phantomjs /usr/bin
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="font-issues">
&lt;a class="heading-anchor-link" href="#font-issues">Font Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="font-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>In practical usage, I used PhantomJS to execute Highcharts chart generation for images, and the charts used Chinese fonts, so it was necessary to install Microsoft YaHei font. The specific operation commands are as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">$ mkdir /usr/share/fonts/chinese
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ cp MicrosoftYaHei.ttf /usr/share/fonts/chinese/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ mkfontscale
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ mkfontdir
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ fc-cache -fv
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># List Chinese fonts
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ fc-list:lang=zh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="mac">
&lt;a class="heading-anchor-link" href="#mac">Mac&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mac"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">brew install phantomjs
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>Using brew for installation is the most convenient method&lt;/code>&lt;/p>
&lt;h2 id="windows">
&lt;a class="heading-anchor-link" href="#windows">Windows&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="windows"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Download the zip package and extract it, for example, place it in &lt;code>D://phantomjs-2.1.1-windows&lt;/code>, then configure environment variables. In the system environment variables, add &lt;code>;D:\phantomjs-2.1.1-windows\bin&lt;/code> to the Path variable.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>PhantomJS provides a powerful headless browser solution for various automation and testing scenarios. The installation process varies by operating system, with Homebrew offering the simplest method on macOS, while Linux and Windows require manual setup. When working with Chinese fonts or other non-standard character sets, remember to install the necessary font packages and configure the font cache properly. These installation steps should help you get PhantomJS up and running efficiently across different platforms.&lt;/p></description></item><item><title>Personal Toolkit — Hardware</title><link>https://en.1991421.cn/2018/04/22/my-tools-hardware/</link><pubDate>Sun, 22 Apr 2018 18:11:13 +0800</pubDate><guid>https://en.1991421.cn/2018/04/22/my-tools-hardware/</guid><description>&lt;p>&lt;strong>A workman must first sharpen his tools.&lt;/strong>&lt;/p>
&lt;p>I continuously optimize work and life through the right “tools.” Looking back, buying a MacBook Pro in mid‑2016 was the best decision of that year and had a lasting impact. It launched my programming journey in earnest, and the ongoing tuning of the laptop made me realize how important software and hardware are — even something as small as managing a bookmarks folder matters. These bits of organization, categorization, and small investments bring long‑term convenience and efficiency.&lt;/p>
&lt;p>OK, here’s my hardware toolkit — mainly to organize my setup and share real impressions. Maybe it helps if you’re on the fence about buying.&lt;/p>
&lt;p>Some models may be dated; follow the classic digital rule of thumb — “buy new, not old” — balanced with budget.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>MacBook Pro 2015 (13-inch, 16 GB, 512 SSD)&lt;/p>
&lt;p>Bought July 2016. Updated to 10.13.4 and still smooth. As a dev, I regret not getting 15-inch — I recommend maxing RAM/SSD; software demands grow.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-22-103053.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>iPhone 8 Plus (64 GB)
Bought late Oct 2017 for 5828 CNY; not a bad deal given promos. Glass back for wireless charging adds weight; I use a silicone case. Strong performance and camera.
For most, Plus is a good choice — it’s not just screen size, but also battery and camera.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-22-102959.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>AirPods
Bought Jan 2018 with no discounts, tempted by the &lt;a href="https://www.bilibili.com/video/av8016203/" target="_blank" rel="noopener">Stroll ad&lt;/a>. Quickly replaced my wired buds — I wear them daily.
Early ridicule aside, users love them and they don’t fall out easily. Sound isn’t audiophile level (my AKG pair is better), but if you want simplicity and style, buy.&lt;/p>
&lt;p>&lt;code>Fun note: looks great on darker skin tones — see the pic.&lt;/code>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-22-103427.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Kindle Paperwhite&lt;/p>
&lt;p>I had a Paperwhite 2 for years, but only relied on it around late 2017/early 2018. Phones are bad for deep reading. Get the lit version — small price delta, big difference. The 3rd‑gen looks noticeably sharper.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-22-104057.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>FILCO MINILA67 (white, brown switches)
A friend’s recommendation. Initially wished I’d bought an 87‑key, but build quality is great. Bluetooth sips power — months between battery changes. For heavy typists, mechanical boards make writing enjoyable.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-22-105136.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>DELL U2518DR
Previously owned the D2515H. Stands are excellent; ports are plentiful.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-22-105252.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>
For buyers: choose the 2018 model — the 2015 stand is noticeably worse compared to the 2018.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Logitech M337 (M336) black
I’ve tried mice from Microsoft, Xiaomi, Lenovo — Logitech remains the go‑to. I chose Bluetooth to save USB ports. It’s small, nicely designed, and portable. Yes, BT can be flaky, but less than expected — still better than a nano dongle.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-22-110834.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>That’s most of the hardware.&lt;/p>
&lt;p>Sharing my desk setup: big monitor as primary, laptop secondary, and a separate Windows machine for Windows‑only tasks. A good desk layout boosts productivity.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-22-104659.png"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p></description></item><item><title>My First Encounter with Surface</title><link>https://en.1991421.cn/2018/04/06/917a1a2/</link><pubDate>Fri, 06 Apr 2018 22:04:01 +0800</pubDate><guid>https://en.1991421.cn/2018/04/06/917a1a2/</guid><description>&lt;blockquote>
&lt;p>I recently needed a Windows laptop. Around me, the most used brand is Lenovo’s ThinkPad. Considering budget and use case (light mobile work), I narrowed it down to a few models: ThinkPad T480, Microsoft Surface Pro 5, Surface Laptop, and Apple’s MacBook/MacBook Air. After some indecision, I went to a SUNING store to get hands‑on impressions.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;em>These direct-sales stores like Suning usually carry a full lineup, so you can experience each device directly. If you actually buy, the price isn’t necessarily higher than JD, and the service is pretty good.&lt;/em>&lt;/p>
&lt;p>Apple’s 2017 MacBook Air was just a routine hardware bump and still lacked Retina; as someone used to iPhone and rMBP, the screen was hard to accept. The MacBook’s screen is too small, so I passed on Macs. Lenovo’s T series has solid specs, expandability, and pricing; aesthetics vs. Surface is a matter of taste.
ThinkPads are classics that stand the test of time. In recent years Microsoft’s laptops have come into their own — Surface is a comeback, and Nadella’s done well. After trying both the Pro and the Laptop, I decided on the Laptop. The Pro’s battery life and screen size lag a bit behind the Laptop for my needs.&lt;/p>
&lt;p>OK, unboxing and getting started.&lt;/p>
&lt;p>Here are a few photos.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-06-IMG_6391-1.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-06-IMG_6384.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>After a few hours of use, here are some impressions:&lt;/p>
&lt;ol>
&lt;li>Touchscreen isn’t essential, but it shines.
After a day, I wished Apple would ship a touchscreen laptop. Using touch to scroll web pages, move through Word, or control video is very convenient. When explaining something to others, pinch/zoom/scroll with both hands feels natural. I’ve really grown to like touch.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-07-Surface-ScrollPage.gif"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/li>
&lt;li>Face recognition needs improvement.
Like iPhone X’s Face ID, it’s convenient compared to fingerprints, but accuracy felt average — with glasses, it sometimes failed. Touch ID only became great by its second generation; hoping Microsoft improves here.&lt;/li>
&lt;li>Clear industrial design language.
You can feel Microsoft’s distinct design language in the Surface. The Alcantara keyboard stands out. Pulling it out in a café definitely has a certain vibe.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-07-IMG_6397.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/li>
&lt;li>Still behind Apple in the details.
The laptop has only one USB port — very stingy — so I had to get a Xiaomi Bluetooth mouse. The beveled bottom for thinness makes USB plugging awkward; that’s a design detail Apple handles better. When closed, the gap is also quite large. Lots of little things for Microsoft to refine.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-07-IMG_6393.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-04-07-IMG_6398.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/li>
&lt;/ol>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>This is my first Microsoft laptop — partly out of curiosity. Overall it’s been good. After a few hours to upgrade Windows to Pro and install productivity apps, it’s become a proper work machine.&lt;/p>
&lt;p>I hope Microsoft keeps pushing the Surface line to catch up with Apple so we all have more good choices.&lt;/p></description></item><item><title>Designing a Token-Based Authentication Flow</title><link>https://en.1991421.cn/2018/02/21/token/</link><pubDate>Wed, 21 Feb 2018 12:02:10 +0800</pubDate><guid>https://en.1991421.cn/2018/02/21/token/</guid><description>&lt;h2 id="authentication-flow">
&lt;a class="heading-anchor-link" href="#authentication-flow">Authentication Flow&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="authentication-flow"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>Client submits login credentials.&lt;/li>
&lt;li>Server validates username and password.&lt;/li>
&lt;li>On success, the server issues a token and returns it to the client.&lt;/li>
&lt;li>The client includes the token in request headers or query parameters thereafter.&lt;/li>
&lt;li>For protected endpoints, the server verifies the token; if valid, it processes the request and responds.&lt;/li>
&lt;/ol></description></item><item><title>Setting 2018 Goals</title><link>https://en.1991421.cn/2018/01/14/2018flag/</link><pubDate>Sun, 14 Jan 2018 00:43:33 +0800</pubDate><guid>https://en.1991421.cn/2018/01/14/2018flag/</guid><description>&lt;blockquote>
&lt;p>2018 has already arrived for half a month. Looking back at 2017, I reflect on my many shortcomings. Here I set some goals to urge myself to implement them one by one in 2018.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-01-13-170025.png"
alt="2018-battery"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Fitness&lt;/p>
&lt;p>Health is the foundation of revolution. Over these 3 years, I&amp;rsquo;ve gone from 67KG in 2014 to 74KG now. My body is no longer in good condition and urgently needs recovery. From now on, exercise 1 hour daily.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Reading&lt;/p>
&lt;p>Whether in work or life, fragmented information or gains from soap operas are often superficial. Reading time should be increased. Without abundant reading, one&amp;rsquo;s perspective naturally becomes narrow.
Over time, this subtly limits oneself, and even when chatting with others, there&amp;rsquo;s less to talk about, which can be embarrassing. So this year I must start reading extensively.&lt;/p>
&lt;p>I recently picked up my Kindle that I bought several years ago and started reading books.&lt;/p>
&lt;p>My reading arrangement is as follows:&lt;/p>
&lt;ul>
&lt;li>1 hour of professional book reading on weekday evenings&lt;/li>
&lt;li>2+ hours of bestseller book reading on non-working days - novels, history, humanities, etc., no restrictions&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Travel&lt;/p>
&lt;p>Accompany parents, accompany grandmother, accompany wife - in short, go out with the closest people. Sometimes when people stay in one place for too long, their thinking inevitably becomes limited.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-01-13-165556.png"
alt="Kindle"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;/ul></description></item><item><title>User Authentication with Frontend–Backend Separation</title><link>https://en.1991421.cn/2018/01/10/frontend-backend-auth/</link><pubDate>Wed, 10 Jan 2018 23:14:01 +0800</pubDate><guid>https://en.1991421.cn/2018/01/10/frontend-backend-auth/</guid><description>&lt;blockquote>
&lt;p>Modern web apps favor frontend–backend separation: frontend focuses on UX, backend on data/logic. This benefits development and maintenance, but it also raises questions about user authentication.&lt;/p>
&lt;/blockquote>
&lt;p>After several projects&amp;rsquo; architecture design and development, I have a more systematic understanding of this area. I&amp;rsquo;m summarizing it here; welcome to criticize and correct me.&lt;/p>
&lt;h1 id="how-to-authenticate-users">How to authenticate users?&lt;/h1>&lt;h2 id="traditional-session--cookie">
&lt;a class="heading-anchor-link" href="#traditional-session--cookie">Traditional: session + cookie&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="traditional-session--cookie"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-01-12-030402.jpg"
alt="Session&amp;#43;Cookie"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>HTTP is stateless, but with the enrichment of requirements, we need to know the user&amp;rsquo;s state to provide different services, which led to the existence of cookies and sessions.&lt;/p>
&lt;h3 id="what-is-a-cookie">
&lt;a class="heading-anchor-link" href="#what-is-a-cookie">What is a cookie?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-is-a-cookie"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;code>Cookies are a solution for maintaining state on the client side&lt;/code>. By definition, a cookie is special information sent by the server to the client, stored as a text file on the client, and then the client brings this special information with every subsequent request to the server.&lt;/p>
&lt;h3 id="what-is-a-session">
&lt;a class="heading-anchor-link" href="#what-is-a-session">What is a session?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-is-a-session"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;code>Sessions maintain state through the server&lt;/code>. Since the term &amp;ldquo;Session&amp;rdquo; has many semantic meanings, it&amp;rsquo;s necessary to clarify its meaning here. First, we usually translate Session as &amp;ldquo;会话&amp;rdquo; (huìhuà), so we can refer to a series of interactions between the client browser and the server as a Session. From this semantic perspective, we talk about the duration of a Session and what operations were performed during the Session; second, Session refers to the storage space opened by the server for the client, and the information stored in it is used to maintain state. From this semantic perspective, we refer to what content is stored in the Session and how to retrieve matching content from the Session based on key values.&lt;/p>
&lt;h3 id="using-session--cookie">
&lt;a class="heading-anchor-link" href="#using-session--cookie">Using session + cookie&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="using-session--cookie"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>When a user logs in, the server creates a session, generates a sessionId, and writes it to the frontend Cookie. In each subsequent request, the sessionId is included, and the server retrieves the corresponding user&amp;rsquo;s identity information through the sessionId.&lt;/p>
&lt;p>Of course, if we are actually developing using the Spring framework, creating a session and writing it to the response Cookie will be automatic.&lt;/p>
&lt;h2 id="a-step-forward-jwt">
&lt;a class="heading-anchor-link" href="#a-step-forward-jwt">A step forward: JWT&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="a-step-forward-jwt"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-01-12-030316.png"
alt="JWT"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Compared to the previous session and cookie mechanism, the token mechanism is an improvement. For user authentication, the server-side session is actually unnecessary and no storage is required.
When a user logs in successfully, the backend issues a token. The user information for identity verification can be directly encrypted and encapsulated in the token. The server returns the token to the frontend, which stores it in a Cookie, while the server doesn&amp;rsquo;t need any storage.
In subsequent requests, the user carries the token in the request header. The server will decrypt the token to check if it has expired or if it is present.&lt;/p>
&lt;h3 id="why-is-this-an-improvement">
&lt;a class="heading-anchor-link" href="#why-is-this-an-improvement">Why is this an improvement?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="why-is-this-an-improvement"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;ol>
&lt;li>The client need not be a browser&lt;/li>
&lt;/ol>
&lt;p>When we use the traditional session + cookie scheme, we actually need to write the session into a cookie, which determines that our frontend must be a browser. In today&amp;rsquo;s popular APP era, this is too limited. For example, an APP actually uses &lt;code>SQLite&lt;/code> as its storage medium.&lt;/p>
&lt;ol start="2">
&lt;li>Auth can be an independent service&lt;/li>
&lt;/ol>
&lt;p>The traditional scheme actually binds user authentication and API services together, while JWT is just a simple token that also carries key user information, so an independent service can be created specifically for issuing tokens.
When we are doing SSO or third-party API integration, we will notice that many authorization services are independent. This is decoupling, this is progress, and this is the charm of this scheme.&lt;/p></description></item><item><title>Tools I Bought in 2017</title><link>https://en.1991421.cn/2018/01/01/2017/</link><pubDate>Mon, 01 Jan 2018 22:55:01 +0800</pubDate><guid>https://en.1991421.cn/2018/01/01/2017/</guid><description>&lt;h2 id="philips-rice-cooker">
&lt;a class="heading-anchor-link" href="#philips-rice-cooker">Philips rice cooker&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="philips-rice-cooker"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Bought in May, price &lt;code>239 CNY&lt;/code>, model HD3060. Nice design, good capacity, suitable for a small household.&lt;/p>
&lt;h2 id="philips-electric-kettle">
&lt;a class="heading-anchor-link" href="#philips-electric-kettle">Philips electric kettle&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="philips-electric-kettle"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Bought in January, price &lt;code>109 CNY&lt;/code>, model HD9303/19. Solid build quality.&lt;/p>
&lt;h2 id="swiss-army-knife">
&lt;a class="heading-anchor-link" href="#swiss-army-knife">Swiss Army knife&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="swiss-army-knife"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Bought in January, price &lt;code>185 CNY&lt;/code>, model Urban Hunter 91mm (15 functions). A household essential.&lt;/p></description></item><item><title>2017 Year-End Summary</title><link>https://en.1991421.cn/2018/01/01/2017/</link><pubDate>Mon, 01 Jan 2018 10:51:48 +0800</pubDate><guid>https://en.1991421.cn/2018/01/01/2017/</guid><description>&lt;blockquote>
&lt;p>2017 ended, and 2018 has arrived.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Looking back at 2017, it was still a year of fast growth and constant challenges for me.&lt;/p>
&lt;/blockquote>
&lt;h2 id="start-of-the-year">
&lt;a class="heading-anchor-link" href="#start-of-the-year">Start of the year&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="start-of-the-year"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The days at the start of the year were hard. On one side I was the frontend lead of Project A, and on the other I was fully responsible for the small Project B. Since my energy had been fully drained throughout 2016, I was almost ready to give up on Project B. I remember calling my boss to vent. He said if I really couldn&amp;rsquo;t hold on, I could drop B. After the call, I thought a lot. In the end, my stubborn resilience, plus my leader&amp;rsquo;s encouragement and support, helped me get through that difficult time.
Projects A and B both ended with good results.&lt;/p>
&lt;ul>
&lt;li>April 1, 2017: Project A finally stabilized after multiple cycles of going online and offline.&lt;/li>
&lt;li>June 9, 2017: The mobile version of Project A launched.&lt;/li>
&lt;li>July 18, 2017: The app of Project A launched.&lt;/li>
&lt;li>May 20, 2017: Project B ended.&lt;/li>
&lt;/ul>
&lt;h2 id="mid-year">
&lt;a class="heading-anchor-link" href="#mid-year">Mid-year&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mid-year"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>As the project stabilized, the team matured, so most implementation work was done by the team and I stepped back a bit. Under continuous high-intensity development, I realized that personal ability and energy are always limited, and the perfection I seek often cannot be achieved in one step. So starting in June, for Project A I focused more on overall architecture and technical research.&lt;/p>
&lt;p>Thanks to continuous grinding and reflection, and sharpening communication skills, I experienced many challenges in just a few months: frontend-backend code sharing, app development plans, frontend performance monitoring, browser compatibility, frontend performance optimization, and more.&lt;/p>
&lt;h2 id="september">
&lt;a class="heading-anchor-link" href="#september">September&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="september"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>While serving as the frontend leader for Project A, a new project quietly began. In mid-September, the boss assigned me to design and develop Project C. With the experience I had, it was easier to start than before. But the difficulty of going from 1 to 2 is no less than going from 0 to 1 - it&amp;rsquo;s just different. While designing, I kept reflecting on the shortcomings of earlier plans.&lt;/p>
&lt;p>So from September, another intense development phase began. Compared with before, I spent less time coding and more time thinking, investigating, and learning. By late December, the platform layer was basically finished and closing out. According to the plan, it should have gone online at the end of December, but the content it depended on was not ready, so it had to be delayed by a month.&lt;/p>
&lt;h2 id="year-end">
&lt;a class="heading-anchor-link" href="#year-end">Year end&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="year-end"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Near the end of the year, Project C was progressing well. I realized many parts of development were mechanical and should be scripted. In September I attended two Thoughtworks events and talked with many peers, which stimulated me. So, chasing the tail end of the year, I decided to push the company to take the first step toward continuous integration. I spent a few days learning about &lt;code>CI, CD, Jenkins&lt;/code>, then started deployment. After three days of trial and error, on December 28 we achieved continuous builds for the frontend project.&lt;/p>
&lt;p>The CI mechanism is mature, and I&amp;rsquo;ve only taken the first step. Once the mechanism is established, everything else follows. Finishing CI was my 2017 closing work, and it felt quite satisfying.&lt;/p>
&lt;blockquote>
&lt;p>I actually wanted to implement CI as early as July, but my understanding and energy were not enough, so I didn&amp;rsquo;t. Looking back, being ahead in ideas but behind in ability doesn&amp;rsquo;t work either. Haha.&lt;/p>
&lt;/blockquote>
&lt;h2 id="outside-of-work">
&lt;a class="heading-anchor-link" href="#outside-of-work">Outside of work&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="outside-of-work"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Outside of work, a few tools entered my stack this year:&lt;/p>
&lt;ul>
&lt;li>&lt;code>GitHub + Travis&lt;/code>: my personal blog&amp;rsquo;s automated build matured. I submit MD files, auto-build and update the site. I write blogs often to summarize knowledge.&lt;/li>
&lt;li>&lt;code>Evernote&lt;/code>: my knowledge note tool. Seamless sync across iPhone, Mac, WeChat official account, and Chrome clipper.&lt;/li>
&lt;li>&lt;code>Inoreader&lt;/code>: RSS reader. Read high-quality articles anytime on the phone without wasting time searching for news.&lt;/li>
&lt;li>&lt;code>TickTick&lt;/code>: task management to improve work efficiency.&lt;/li>
&lt;li>&lt;code>Eudic&lt;/code>: Mac and iPhone sync. Poor English and doing tech? No!&lt;/li>
&lt;li>&lt;code>Dell U2518DR, U2515H&lt;/code>: I bought these two monitors this year. Each for home and office. The displays have helped me a lot. Thanks to the recommendations from &amp;ldquo;digital veteran Di&amp;rdquo; and Lao Zhang. The screens are big so I can see more content. Dell&amp;rsquo;s stands are excellent too - the difference is obvious.&lt;/li>
&lt;/ul>
&lt;p>As the tool community slogan says, to do a good job, one must first sharpen the tools. Exploring these tools greatly improved my learning efficiency.&lt;/p>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>I believe work and learning are intertwined. Work involves constant learning, and learning in turn affects work.&lt;/p>
&lt;p>From solo combat to leading a team, breaking down features; from developer to frontend leader to product manager, taking full ownership of the product - these role shifts came with one tough challenge after another. I&amp;rsquo;m still far from the goal, but at least each step has landed steadily.&lt;/p>
&lt;p>2017 wasn&amp;rsquo;t easy. 2018 will likely be harder, but what&amp;rsquo;s the point if it&amp;rsquo;s easy? Charging into challenges is the life I seek.&lt;/p>
&lt;p>I still want to thank my leaders, my family, and all the excellent people around me. They give me pressure and also make me feel alive.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2018-01-01-045311.jpg"
alt="2017 Year-End Summary - Fig 1"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p></description></item><item><title>How to Make Phone Interaction GIFs</title><link>https://en.1991421.cn/2017/10/17/how-to-make-mobile-gif/</link><pubDate>Tue, 17 Oct 2017 21:45:01 +0800</pubDate><guid>https://en.1991421.cn/2017/10/17/how-to-make-mobile-gif/</guid><description>&lt;blockquote>
&lt;p>When documenting mobile workflows or writing tutorials, GIFs help readers grasp a sequence instantly. Here’s how I capture them.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/wakatime-oauth.gif"
alt="gif"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>The pipeline is simple: record video → convert the clip to GIF. Tools I use:&lt;/p>
&lt;h2 id="screen-recording">
&lt;a class="heading-anchor-link" href="#screen-recording">Screen Recording&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="screen-recording"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>QuickTime (macOS, built-in)&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-10-17-135412.jpg"
alt="QuickTime"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="http://www.tlxsoft.com/index1.htm" target="_blank" rel="noopener">HyperCam&lt;/a> (Windows)&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-10-17-150355.jpg"
alt="HyperCam screenshot"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="convert-video-to-gif">
&lt;a class="heading-anchor-link" href="#convert-video-to-gif">Convert Video to GIF&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="convert-video-to-gif"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Desktop apps&lt;/p>
&lt;ul>
&lt;li>PicGIF (macOS)&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-10-17-135630.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="http://www.pcfreetime.com/formatfactory/CN/index.html" target="_blank" rel="noopener">Format Factory&lt;/a> (Windows)&lt;/li>
&lt;/ul>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-10-17-135933.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Web tools&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://image.online-convert.com/convert-to-gif" target="_blank" rel="noopener">convert-to-gif&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="notes">
&lt;a class="heading-anchor-link" href="#notes">Notes&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="notes"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>To mirror a phone to desktop, use QuickTime or a companion app and record as usual.&lt;/li>
&lt;/ul></description></item><item><title>POST Data Encoding Methods</title><link>https://en.1991421.cn/2017/10/16/post/</link><pubDate>Mon, 16 Oct 2017 20:42:54 +0800</pubDate><guid>https://en.1991421.cn/2017/10/16/post/</guid><description>&lt;blockquote>
&lt;p>Postman is a powerful API debugging tool. When executing POST requests, you&amp;rsquo;ll notice there are 4 format options for the body. What do these four options mean and what are their use cases? After researching various sources, I&amp;rsquo;ve summarized them below:
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-10-16-125105.jpg"
alt="postman-post"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;/blockquote>
&lt;p>Although Postman displays form-data, x-www-form-urlencoded, raw, and binary, the actual data formats submitted are not these 4 types, but rather multipart/form-data, application/x-www-form-urlencoded, application/json, and text/xml.&lt;/p>
&lt;h2 id="applicationx-www-form-urlencoded">
&lt;a class="heading-anchor-link" href="#applicationx-www-form-urlencoded">application/x-www-form-urlencoded&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="applicationx-www-form-urlencoded"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>When a web browser sends a POST request from a web form element, the default Internet media type is &amp;ldquo;application/x-www-form-urlencoded&amp;rdquo;.[8] This is a format for encoding key-value pairs with possibly duplicate keys. Each key-value pair is separated by an &amp;lsquo;&amp;amp;&amp;rsquo; character, and each key is separated from its value by an &amp;lsquo;=&amp;rsquo; character. Keys and values are both escaped by replacing spaces with the &amp;lsquo;+&amp;rsquo; character and then using URL encoding on all other non-alphanumeric[9] characters.&lt;/p>
&lt;/blockquote>
&lt;p>The description above is from &lt;a href="https://en.wikipedia.org/wiki/POST_%28HTTP%29" target="_blank" rel="noopener">WIKI&lt;/a>&lt;/p>
&lt;p>For native browser form elements, if the enctype attribute is not set, the data will ultimately be submitted using the application/x-www-form-urlencoded format.&lt;/p>
&lt;h2 id="multipartform-data">
&lt;a class="heading-anchor-link" href="#multipartform-data">multipart/form-data&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="multipartform-data"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When form submissions contain files (such as image files), this data format is required.&lt;/p>
&lt;h2 id="applicationjson">
&lt;a class="heading-anchor-link" href="#applicationjson">application/json&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="applicationjson"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>The application/json Content-Type is commonly seen as a response header, but increasingly, people are using it as a request header to tell the server that the message body is a serialized JSON string. This makes it easy to submit complex structured data and is particularly suitable for RESTful APIs.&lt;/p>
&lt;h2 id="rawbinary">
&lt;a class="heading-anchor-link" href="#rawbinary">raw，binary&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="rawbinary"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>raw refers to raw data, while binary refers to binary data.&lt;/p>
&lt;ul>
&lt;li>When raw is selected, a large input box appears where you can enter whatever you want to submit. This can be text, JSON, XML, HTML, etc.&lt;/li>
&lt;li>binary is specifically used to submit binary data of files, and only one file can be submitted at a time.&lt;/li>
&lt;/ul>
&lt;h2 id="reference-articles">
&lt;a class="heading-anchor-link" href="#reference-articles">Reference Articles&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="reference-articles"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1" target="_blank" rel="noopener">W3C Form content types&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.w3.org/TR/html-json-forms/" target="_blank" rel="noopener">W3C html-json-forms&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://chayangge.com/2016/12/01/POST%E6%8F%90%E4%BA%A4%E6%95%B0%E6%8D%AE%E7%9A%84%E5%B8%B8%E8%A7%81%E7%BC%96%E7%A0%81%E6%96%B9%E5%BC%8F/" target="_blank" rel="noopener">Common POST Data Encoding Methods&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.voidcn.com/article/p-figxdxhn-bdu.html" target="_blank" rel="noopener">Common POST Submission Types&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Understanding the different POST data encoding methods is crucial for effective API development and debugging. Each method serves specific purposes:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>application/x-www-form-urlencoded&lt;/strong>: The default for simple form submissions&lt;/li>
&lt;li>&lt;strong>multipart/form-data&lt;/strong>: Essential for file uploads&lt;/li>
&lt;li>&lt;strong>application/json&lt;/strong>: Ideal for structured data in RESTful APIs&lt;/li>
&lt;li>&lt;strong>raw/binary&lt;/strong>: Provides flexibility for custom data formats&lt;/li>
&lt;/ul>
&lt;p>Choosing the right encoding method depends on your specific use case and the data you need to transmit. Tools like Postman make it easy to experiment with different formats during development.&lt;/p></description></item><item><title>PHP Environment Setup</title><link>https://en.1991421.cn/2017/10/02/php-env-setup/</link><pubDate>Mon, 02 Oct 2017 22:28:32 +0800</pubDate><guid>https://en.1991421.cn/2017/10/02/php-env-setup/</guid><description>&lt;blockquote>
&lt;p>Debating which programming language is superior is quite pointless - languages are tools, and what matters is the thinking behind them. Choose what suits your needs and preferences.
Objectively speaking, PHP is an excellent language that has thrived for many years and certainly has its merits.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Since some legacy projects are developed in PHP, it&amp;rsquo;s essential to ensure the development machine has a proper PHP environment. Here&amp;rsquo;s a record of the PHP environment setup process.&lt;/p>
&lt;/blockquote>
&lt;h2 id="windows">
&lt;a class="heading-anchor-link" href="#windows">Windows&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="windows"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Recommended to use &lt;code>phpstudy&lt;/code> - &lt;a href="http://www.phpstudy.net/" target="_blank" rel="noopener">Download Link&lt;/a>&lt;/p>
&lt;p>Note: phpstudy does not have a Mac version&lt;/p>
&lt;p>phpstudy comes pre-packaged with:&lt;/p>
&lt;ul>
&lt;li>Apache&lt;/li>
&lt;li>PHP&lt;/li>
&lt;li>etc.&lt;/li>
&lt;/ul>
&lt;p>By installing this tool, you can quickly set up the environment.&lt;/p>
&lt;p>Of course, XAMPP and wampserver are also viable alternatives.&lt;/p>
&lt;h2 id="mac">
&lt;a class="heading-anchor-link" href="#mac">Mac&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mac"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Starting from OS X 10.0.0, PHP has been included as a standard component in Mac systems. Original documentation can be found &lt;a href="http://php.net/manual/zh/install.macosx.bundled.php" target="_blank" rel="noopener">here&lt;/a>. However, if you try to access it directly through a browser, you may encounter the following errors.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-10-03-86D27F6433EFDC3E188CCD07D6519A7B.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-10-03-ED7F19B676EE1E40A05ABDAC5A41C737.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>
Therefore, it&amp;rsquo;s recommended to reinstall PHP. Execute the following command, then configure it in PHPStorm.
&lt;code>curl -s http://php-osx.liip.ch/install.sh | bash -s 5.6&lt;/code>
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-10-03-093521.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>
After this, accessing the page through the browser should work properly.&lt;/p>
&lt;h2 id="apache-configuration">
&lt;a class="heading-anchor-link" href="#apache-configuration">Apache Configuration&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="apache-configuration"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>PHP projects need to run under Apache. Simply configuring the path may result in 403 errors, so additional configuration is required. Below is the modified configuration - it&amp;rsquo;s recommended to backup the original configuration file before making changes.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">&amp;lt;Directory /&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Options Indexes FollowSymLinks
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> AllowOverride None
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Order deny,allow
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Allow from all
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;/Directory&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">DocumentRoot &amp;#34;/Users/juliana/newsp/testing/Test/www&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;Directory &amp;#34;/Users/juliana/newsp/testing/Test/www&amp;#34;&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> #
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # Possible values for the Options directive are &amp;#34;None&amp;#34;, &amp;#34;All&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # or any combination of:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> #
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # Note that &amp;#34;MultiViews&amp;#34; must be named *explicitly* --- &amp;#34;Options All&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # doesn&amp;#39;t give it to you.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> #
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # The Options directive is both complicated and important. Please see
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # http://httpd.apache.org/docs/2.4/mod/core.html#options
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # for more information.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> #
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Options FollowSymLinks Multiviews
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> MultiviewsMatch Any
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> #
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # AllowOverride controls what directives may be placed in .htaccess files.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # It can be &amp;#34;All&amp;#34;, &amp;#34;None&amp;#34;, or any combination of the keywords:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # AllowOverride FileInfo AuthConfig Limit
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> #
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # AllowOverride None
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> AllowOverride All
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> #
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # Controls who can get stuff from this server.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> #
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Require all granted
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;/Directory&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="final-thoughts">
&lt;a class="heading-anchor-link" href="#final-thoughts">Final Thoughts&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="final-thoughts"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Setting up a proper PHP development environment is essential for working with legacy PHP projects. The tools and configurations mentioned here provide a solid foundation for PHP development on both Windows and macOS platforms. Remember to always backup your configuration files before making changes, and test your setup thoroughly to ensure everything works as expected.&lt;/p></description></item><item><title>Common Issues with Xcode Simulator</title><link>https://en.1991421.cn/2017/09/29/xcode-simulator/</link><pubDate>Fri, 29 Sep 2017 11:11:51 +0800</pubDate><guid>https://en.1991421.cn/2017/09/29/xcode-simulator/</guid><description>&lt;blockquote>
&lt;p>Xcode’s Simulator makes it convenient to test apps without a physical device. Along the way you’ll hit some common issues — here’s a quick summary.&lt;/p>
&lt;/blockquote>
&lt;ul>
&lt;li>&lt;a href="#uninstalling-simulators">Uninstalling Simulators&lt;/a>&lt;/li>
&lt;li>&lt;a href="#input-method-issues">Input Method Issues&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="uninstalling-simulators">
&lt;a class="heading-anchor-link" href="#uninstalling-simulators">Uninstalling Simulators&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="uninstalling-simulators"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>You can see downloaded simulator runtimes under Xcode Components.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-09-29-030917.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>To delete a specific simulator runtime, go to &lt;code>/Library/Developer/CoreSimulator/Profiles/Runtimes&lt;/code> and remove the target runtime.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-09-29-030854.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Back in Xcode → Components, you’ll see the simulator listed as “not installed”.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-09-29-031422.jpg"
alt=""
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="input-method-issues">
&lt;a class="heading-anchor-link" href="#input-method-issues">Input Method Issues&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="input-method-issues"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>When testing, you may find typing Chinese on macOS still shows as English in the Simulator. This is due to the iOS language settings in the simulated device.&lt;/p>
&lt;p>&lt;em>Issues inside the Simulator are equivalent to a real device, so fix them the same way.&lt;/em>&lt;/p>
&lt;p>In my case, the Simulator didn’t have Chinese because the default language followed my Mac’s English locale. With English as the initial language, the Chinese keyboard isn’t present; you need to add it manually.&lt;/p>
&lt;p>&lt;code>Settings → General → Keyboard&lt;/code>&lt;/p></description></item><item><title>TypeScript Version Always Shows 1.0</title><link>https://en.1991421.cn/2017/09/06/ts1-0/</link><pubDate>Wed, 06 Sep 2017 14:09:53 +0800</pubDate><guid>https://en.1991421.cn/2017/09/06/ts1-0/</guid><description>&lt;blockquote>
&lt;p>On Windows, &lt;code>tsc --version&lt;/code> showed &lt;code>1.0.3.0&lt;/code> even though I’d installed TypeScript 2.3.4. Running &lt;code>where tsc&lt;/code> revealed the culprit.&lt;/p>
&lt;/blockquote>
&lt;h2 id="version-output">
&lt;a class="heading-anchor-link" href="#version-output">Version Output&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="version-output"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-09-06-061148.jpg"
alt="version screenshot"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="system-path">
&lt;a class="heading-anchor-link" href="#system-path">System PATH&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="system-path"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-09-06-061237.jpg"
alt="path screenshot"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>The PATH pointed to &lt;code>C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0&lt;/code>—the compiler bundled with Visual Studio.&lt;/p>
&lt;h2 id="fix">
&lt;a class="heading-anchor-link" href="#fix">Fix&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="fix"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Remove that path entry and rerun &lt;code>tsc --version&lt;/code>:
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-09-06-061345.jpg"
alt="after removing"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Now the correct version appears.&lt;/p></description></item><item><title>Solving the Missing SDK Manager Issue in Android Studio</title><link>https://en.1991421.cn/2017/07/30/androidstudiosdk/</link><pubDate>Sun, 30 Jul 2017 20:12:40 +0800</pubDate><guid>https://en.1991421.cn/2017/07/30/androidstudiosdk/</guid><description>&lt;h2 id="the-problem">
&lt;a class="heading-anchor-link" href="#the-problem">The Problem&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="the-problem"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Although I&amp;rsquo;m working on hybrid development, I still need an Android environment to package Android applications. The Android SDK can be downloaded and configured separately, but using Android Studio for management and configuration is more convenient. However, when I launched the software, I found that there was no SDK configuration option.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-07-30-121637.jpg"
alt="fail"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Looking at the official website introduction, I found that theoretically, it should display the interface below:
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-07-30-121910.jpg"
alt="official"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="solution">
&lt;a class="heading-anchor-link" href="#solution">Solution&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="solution"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>After searching for quite a while, I finally found the solution. Go to the plugin management:
&lt;code>Configuration &amp;gt; Plugin &amp;gt; Android Support Plugin&lt;/code>, make sure this plugin is in the enabled state, and click OK.
&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-07-30-130152.jpg"
alt="Android Support Plugin"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Restart the IDE and it should work.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-07-30-121403.jpg"
alt="successful"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;h2 id="analysis">
&lt;a class="heading-anchor-link" href="#analysis">Analysis&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="analysis"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Android Studio was developed by JetBrains based on IntelliJ IDEA. IDEA is for Java development, while Android is built on top of Java. Therefore, Android support is provided in the form of a plugin, which means Android Studio can work perfectly fine even without Android development capabilities.&lt;/p></description></item><item><title>How to Use iPic Image Hosting Tool (Step-by-Step Guide)</title><link>https://en.1991421.cn/2017/07/22/ipic/</link><pubDate>Sat, 22 Jul 2017 20:06:05 +0800</pubDate><guid>https://en.1991421.cn/2017/07/22/ipic/</guid><description>&lt;blockquote>
&lt;p>When writing Markdown blogs, images or GIFs are often needed. Uploading to an image hosting service is usually the best approach.&lt;/p>
&lt;/blockquote>
&lt;h2 id="previous-approach">
&lt;a class="heading-anchor-link" href="#previous-approach">Previous Approach&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="previous-approach"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ul>
&lt;li>Open browser and go to image hosting website&lt;/li>
&lt;li>Multiple steps: [Object Storage → Content Management → Upload File → Copy Link]&lt;/li>
&lt;li>Paste the link into the Markdown blog file&lt;/li>
&lt;/ul>
&lt;p>This workflow is tedious and repetitive: the steps are the same each time; only the asset changes. I’d been looking for a way to automate and streamline this part of my writing process. By chance I joined the “Tools” group, met many friends, and discovered lots of great utilities — including &lt;code>iPic&lt;/code>.&lt;/p>
&lt;h2 id="after-using-ipic">
&lt;a class="heading-anchor-link" href="#after-using-ipic">After Using iPic&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="after-using-ipic"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Here’s what uploading looks like with iPic:&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/blog/2017-07-22-121516.jpg"
alt="use-iPic"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p>
&lt;p>Now when writing, I can just drag images into iPic, or send screenshots directly from iPic to the target image host. After a successful upload, the link is automatically copied to the system clipboard — then I simply paste it into the Markdown file.&lt;/p>
&lt;p>iPic really is a great tool that streamlines the entire “upload to image host” flow. Thumbs up to Jason (the creator of iPic).&lt;/p>
&lt;p>Official iPic page: &lt;a href="https://toolinbox.net/iPic/" target="_blank" rel="noopener">click here&lt;/a>&lt;/p>
&lt;h2 id="what-about-windows">
&lt;a class="heading-anchor-link" href="#what-about-windows">What about Windows?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="what-about-windows"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Recommended: &lt;a href="http://mpic.lzhaofu.cn/" target="_blank" rel="noopener">MPic&lt;/a>&lt;/p></description></item><item><title>The Programmer's Journey</title><link>https://en.1991421.cn/2017/07/15/programmer-practice/</link><pubDate>Sat, 15 Jul 2017 22:09:24 +0800</pubDate><guid>https://en.1991421.cn/2017/07/15/programmer-practice/</guid><description>&lt;blockquote>
&lt;p>July 2014, graduated from university. July 2017, 3 years of work. It&amp;rsquo;s time to record, reflect on the past, present, and future. Sorting through everything I&amp;rsquo;ve done before gives me some closure.&lt;/p>
&lt;/blockquote>
&lt;p>Thanks to good memory, I can clearly trace back every job I&amp;rsquo;ve done since starting work. Since it involves commercial information, it&amp;rsquo;s better to use code names. I understand them perfectly myself, while others can just get a general idea, haha.&lt;/p>
&lt;h2 id="2014">
&lt;a class="heading-anchor-link" href="#2014">2014&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2014"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="early-year">
&lt;a class="heading-anchor-link" href="#early-year">Early Year&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="early-year"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>In the first few months (February-April), I did data collection, mainly writing regular expressions based on webpage source structure for matching and scraping. The tool used was &lt;code>LocoySpider&lt;/code>. These seemingly tedious months actually brought several gains:&lt;/p>
&lt;ul>
&lt;li>Regular Expressions&lt;/li>
&lt;/ul>
&lt;p>These were learned in university programming courses, but learning and using are two different things. In practical application, I have to admire the authors of regular expressions for designing such beautiful things. When a novice user uses text search in Word or Windows system search, how would they know that regular expression concepts are behind it? One could say that text search is fundamentally based on regex concepts.&lt;/p>
&lt;ul>
&lt;li>Web Crawling, Data Collection&lt;/li>
&lt;/ul>
&lt;p>This experience gave me initial understanding of data collection and crawling, providing solid foundational knowledge of HTTP protocol, webpage source code, website structure, etc. Although I didn&amp;rsquo;t go deep into it, these had a big impact on me. I&amp;rsquo;ve always believed that technologies influence and interconnect with each other. Understanding leads to benefits, it&amp;rsquo;s just a matter of when those benefits come.&lt;/p>
&lt;h3 id="july-august">
&lt;a class="heading-anchor-link" href="#july-august">July-August&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="july-august"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>I started joining a project team for web development. This project was called &lt;code>A&lt;/code>, and the development cycle spanned until Chinese New Year 2015. The web framework used was &lt;code>Grails&lt;/code> (which of course was based on Java&amp;rsquo;s &lt;code>SpringMVC&lt;/code>). This was my first real web development project. I remember I was only responsible for one module initially, but as development progressed, my curious and thoughtful nature meant I didn&amp;rsquo;t just understand my own part but the entire system. Over time during development, both my coding skills and understanding of the entire platform reached a certain level.&lt;/p>
&lt;p>During this period, a colleague &lt;code>Fu*&lt;/code> resigned, citing stress as the reason. Since they couldn&amp;rsquo;t be replaced quickly, I took over his development work. Since our two areas had overlap, it wasn&amp;rsquo;t too problematic. Later, I became responsible for the main modules of the entire project. By this time, I basically controlled the development of the entire web platform, except for the personal center section. In early 2015, the web platform successfully launched. For me, after half a year of training, I felt the joy of development for the first time.
Reflecting, I gained several things:&lt;/p>
&lt;ul>
&lt;li>fusioncharts, pd4ml, solrj, etc.
In actual development, different requirements called for different solutions. For example, fusioncharts for visualization charts, pd4ml for PDF generation (like HTML to PDF), solrj as the Java interface package for the search tool Solr, etc. These technologies aren&amp;rsquo;t directly related, but they can all be called &amp;ldquo;wheels&amp;rdquo; (ready-made solutions). Through continuous development and using these, I learned to leverage mature solutions and use official APIs. In interesting terms: use existing wheels, do your part well, and solve problems with available tools.&lt;/li>
&lt;li>Java
The project framework was built by my leader &lt;code>Li*&lt;/code>. As I kept developing, I increasingly appreciated how well the framework was built. I remember actively telling the CEO how good it was - concise, standardized code. My leader responded: &amp;ldquo;Yes, that&amp;rsquo;s what an architect does. He has rich experience, so no matter how you develop, you can&amp;rsquo;t escape his framework.&amp;rdquo; I agreed and also realized the importance of continuously absorbing others&amp;rsquo; technology, experience, even coding style.&lt;/li>
&lt;/ul>
&lt;p>I&amp;rsquo;ve always believed that one should keep learning constantly, absorbing characteristics from anyone better than you. This process should be like a sponge - throw it in water and it quickly absorbs moisture.&lt;/p>
&lt;p>I remember when the leader needed to build several internal systems, he used A as the framework. They were basically the same with minor modifications. Since I was most familiar with this system, I used SVN branching to create 4 similar systems.&lt;/p>
&lt;h2 id="2015">
&lt;a class="heading-anchor-link" href="#2015">2015&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2015"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="early-year-1">
&lt;a class="heading-anchor-link" href="#early-year-1">Early Year&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="early-year-1"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>In early 2015, due to business needs, the company needed to develop internal systems. Since I personally enjoy challenges and work, I was assigned the most important part - the task management module. The real difficulty wasn&amp;rsquo;t in development but in architecture. I remember drawing flowcharts repeatedly, discarding and redrawing them using &lt;code>Microsoft Visio&lt;/code>. I communicated with my leader multiple times during this period - after all, he had rich experience. Eventually, I conquered this toughest challenge.&lt;/p>
&lt;ul>
&lt;li>Flowcharts
This project&amp;rsquo;s biggest impact on me was flowcharts, i.e., design. Because design affects the entire development process, post-launch maintenance, and future uncertain feature additions - essentially scalability.&lt;/li>
&lt;li>Communication
&lt;code>Li*&lt;/code> was the most excellent person in our company, and I think the smartest too (boss, if you see this, don&amp;rsquo;t be angry - I&amp;rsquo;m limiting &amp;ldquo;smart&amp;rdquo; to coding and architecture here, hehe). When I couldn&amp;rsquo;t figure something out or wasn&amp;rsquo;t sure about my design, I often talked with him. I realized that thorough consideration and scientific system design reduce future costs. Learning from others&amp;rsquo; experience is crucial. Indeed, through communication, I discovered deficiencies in my thinking. With his guidance, I improved my design shortcomings. Development went very smoothly, and even today, I think that design was good.&lt;/li>
&lt;/ul>
&lt;h3 id="mid-year">
&lt;a class="heading-anchor-link" href="#mid-year">Mid-Year&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="mid-year"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>In mid-2015, I started participating in a website project &lt;code>B&lt;/code>, still using the &lt;code>Grails&lt;/code> framework. This project was more complex than 2014&amp;rsquo;s A. In actual development, there were many small issues because the previous system was internal and didn&amp;rsquo;t have large-scale user feedback, while this one served a substantial user base, revealing many detailed problems.
This project&amp;rsquo;s development gave me several gains:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Collaboration
Previous projects had collaboration too, but this project belonged to another department. Although the company wasn&amp;rsquo;t large, there were organizational structures. This project&amp;rsquo;s development gave me deep understanding of colleagues from unfamiliar departments and insight into their work.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Refactoring
During development, I worked on a module called Alert, originally done by a colleague &lt;code>Zhang*&lt;/code>. When I looked at it, I found it was overly complex for a simple function. But directly overturning someone else&amp;rsquo;s work wasn&amp;rsquo;t feasible, so optimization and refactoring were needed.&lt;/p>
&lt;p>So I organized the original logic, drew flowcharts for what the function should actually do, and adjusted the logic to achieve the same functionality. I remember after my refactoring, code volume reduced by 40%. Due to time constraints, I didn&amp;rsquo;t complete the full refactoring, but I was happy with the results - I truly simplified complexity and improved maintainability.&lt;/p>
&lt;blockquote>
&lt;p>I remember a theory from a Java book by Daniel and his father: the larger the code volume, the higher the maintenance cost. I completely agree.&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;/ul>
&lt;h3 id="other">
&lt;a class="heading-anchor-link" href="#other">Other&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="other"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>In the second half of 2015, besides B&amp;rsquo;s development, I also participated in maintenance for some government client projects, including PHP project maintenance, APP maintenance, and some platform assistance. Overall, these projects involved less technical support and more client communication and coordination.
This experience gave me several insights:&lt;/p>
&lt;ul>
&lt;li>Clients as Friends
Through continuous client communication, I truly realized that relationships significantly impact efficiency and results. Usually we technicians just follow requirements from above, but there are problems in this process. Physics talks about energy loss - even when a client makes a product request to the company, there&amp;rsquo;s loss when it&amp;rsquo;s communicated down through layers.
Because I constantly communicated with clients and built good relationships, clients often gave flexibility based on actual circumstances.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>I remember once our service crashed abnormally. For security reasons, there was no remote desktop access, meaning I had to go on-site. The round trip would take over 2 hours, but actually being there would only take 1 minute to restart the service. The client told me: &amp;ldquo;How about you remotely operate my computer as a jump server to connect to the target server?&amp;rdquo; I was thrilled and thanked them profusely.
This saved over 2 hours - significant cost savings for both the company and myself.&lt;/p>
&lt;/blockquote>
&lt;h3 id="emergency-response">
&lt;a class="heading-anchor-link" href="#emergency-response">Emergency Response&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="emergency-response"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>September 2015 was the &lt;code>70th Anniversary of the Anti-Japanese War Victory&lt;/code> - unforgettable for the world, our country, and also unforgettable and tough for me. On the eve of the anniversary, I spent the night in the client&amp;rsquo;s server room. The reason was security concerns - to prevent server hacking and negative impacts. Multiple levels required guaranteed security, with immediate response if problems occurred. Considering that staying home might lead to inadequate response time, I volunteered to guard overnight. Actually, only two companies ended up doing overnight duty - the other was the client&amp;rsquo;s primary service provider. The night passed without incident.&lt;/p>
&lt;p>Thinking about service providers - so many, yet only two were willing to do night duty. I still built a good image for our company - at least we were one of those two. I remember a joke by Zhou Libo: &amp;ldquo;Even Lei Feng wrote diaries about his good deeds, afraid people wouldn&amp;rsquo;t know.&amp;rdquo;&lt;/p>
&lt;p>At such critical moments, ensuring full protection is the service provider&amp;rsquo;s responsibility - no excuses.&lt;/p>
&lt;h2 id="2016">
&lt;a class="heading-anchor-link" href="#2016">2016&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2016"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="early-year-2">
&lt;a class="heading-anchor-link" href="#early-year-2">Early Year&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="early-year-2"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Early in the year, company business wasn&amp;rsquo;t tight, giving me ample time to learn. A long-term client needed a content APP, and the company gave me this opportunity to develop. I remember spending 2-3 months on APP development, covering both frontend and backend. Frontend used ionic1, backend used phpcms2008. I faced various obstacles - my thinking wasn&amp;rsquo;t adjusted from previous Java development, plus PHP was challenging. It was tough - constantly reading materials, researching. Finally, the APP launched around April.&lt;/p>
&lt;p>This app build was genuinely tough. I remember the boss urging me repeatedly about why it still wasn’t done—he figured an experienced person could finish both frontend and backend in about a month. I kept answering that I wanted to do it properly and be satisfied with the result first.&lt;/p>
&lt;p>Technically, this project wasn&amp;rsquo;t difficult, but for me, it was comprehensive training - thorough. Key points:&lt;/p>
&lt;ul>
&lt;li>Frequent client communication for requirement analysis and understanding&lt;/li>
&lt;li>PS work for APP mockups, icons, and other UI tasks&lt;/li>
&lt;li>PHPCMS deployment and content management system setup, learning PHP, customized development based on CMS&lt;/li>
&lt;li>Creating API interfaces following REST standards&lt;/li>
&lt;li>APP development with ionic1+angularjs&lt;/li>
&lt;li>Message push implementation with JPUSH&lt;/li>
&lt;li>APP version control&lt;/li>
&lt;li>Android packaging, certificate signing&lt;/li>
&lt;li>iOS packaging and review&lt;/li>
&lt;li>CMS platform production environment deployment&lt;/li>
&lt;/ul>
&lt;p>And many other scattered issues. When it finally launched, that moment when I could search for my own developed APP in the store - even though the author showed the company name, not mine - I was joyful because I knew I developed it.&lt;/p>
&lt;p>The APP had a registration function. I wrote a feature where new user registrations would email the editors, plus me as technical support. Even now, whenever I receive registration emails, I&amp;rsquo;m happy because I know there are new users.&lt;/p>
&lt;p>This APP hasn&amp;rsquo;t been updated since 2016 development. I regret this because it was like my own child, but the client&amp;rsquo;s focus wasn&amp;rsquo;t there, so no funding to maintain it. However, its significance to me is great because it gave me my first experience of full project ownership. I knew I would soon appreciate this experience, and I believe my dedication will be rewarded.&lt;/p>
&lt;h3 id="main-theme">
&lt;a class="heading-anchor-link" href="#main-theme">Main Theme&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="main-theme"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>After completing the 3-month APP development, the company assigned me to a project team for a major project development called &lt;code>C&lt;/code>.&lt;/p>
&lt;p>Actually, I didn&amp;rsquo;t expect this project development to be so rugged, so painful, yet so fulfilling and exciting. It could be said to have trained me to the maximum extent and depth.&lt;/p>
&lt;p>About &lt;code>technology selection&lt;/code>, we struggled for a long time. SpringMVC is a very stable and mature framework, which should be the most efficient and time-saving. Plus, our team was most familiar with Java.
But technology keeps advancing, and considering architectural drawbacks from previous projects and the need to update the company&amp;rsquo;s tech stack, we ultimately chose Angular2 as our frontend framework, expressJS as backend framework, and jersey as service framework. Abstractly, it would be 3 layers. Actually, this architecture is similar to Alibaba&amp;rsquo;s architecture. Angular2+expressJS can be collectively called &amp;ldquo;big frontend&amp;rdquo; - a term I really like.
After technology selection was settled, we started design and development, but it wasn&amp;rsquo;t actually smooth. Main reasons were two points:&lt;/p>
&lt;ol>
&lt;li>The ng+expressJS platform architecture requires frontend development expertise, which our company lacked in terms of strong talent pool&lt;/li>
&lt;li>ng2 itself was very new - when the project started, ng2 had just released RC version
According to company staffing arrangements, this big frontend part would be done by me and a colleague. ng2 frontend development itself had 3 language choices:
&lt;ul>
&lt;li>TypeScript&lt;/li>
&lt;li>JavaScript&lt;/li>
&lt;li>Dart&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>But the official recommendation was &lt;code>TypeScript&lt;/code>. This was my first time hearing about this language. What should we choose? I was conflicted. However, since official recommendation was TypeScript, I thought we should consider it first. I checked the language syntax - it&amp;rsquo;s actually object-oriented. If you&amp;rsquo;ve learned JAVA, it&amp;rsquo;s not that difficult. Both my colleague and I are people who aren&amp;rsquo;t afraid of difficulties and have open learning attitudes, so we finally decided on it.
So development work began. The other colleague, being more skilled at UI work, handled the page display part. I, with relatively solid JAVA foundation and accumulated implementation experience, plus being very familiar with the business, handled the main framework, logic, and functionality.&lt;/p>
&lt;p>Actually, the development difficulties were worse than imagined. ng2 itself was still RC, documentation wasn&amp;rsquo;t in Chinese. Fortunately, English is one of my strengths, so I wasn&amp;rsquo;t afraid. But the massive reading was still a significant challenge. I spent almost every day dealing with English documentation. Plus, many detailed technical points - since the company lacked talent in this area, I had to find answers myself.&lt;/p>
&lt;blockquote>
&lt;p>Google and GitHub became my most frequently visited sites during this stretch.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>During this time, I joined a QQ group with some real experts. I always had piles of questions, and several people consistently answered enthusiastically, giving me significant help. One called K had really high frontend skills. Through this, I constantly received both criticism and guidance from him, continuously improving. He pushed me to do many things I lacked courage for, like ng2 components - initially I didn&amp;rsquo;t know how to design them well, he said &amp;ldquo;look at material source code.&amp;rdquo;
I knew he was right because material is the official ng component library - theoretically its design must be worth referencing. But reading source code was still challenging for me. Sometimes it&amp;rsquo;s just that little bit of courage missing.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Finally, I broke through my psychological barriers and started reading source code. Over time, it didn&amp;rsquo;t seem so difficult anymore, and I learned many practical techniques from these excellent codes.&lt;/p>
&lt;/blockquote>
&lt;p>During continuous development, time kept moving forward, but we encountered several fatal problems that made me somewhat discouraged - one was compatibility, the other was performance.&lt;/p>
&lt;ul>
&lt;li>ng2&amp;rsquo;s official compatibility list was IE10+. To support IE9, you needed to add compatibility packages, but in practice, even IE11 had problems. I became less confident - if IE11 wasn&amp;rsquo;t supported, the project would directly fail&lt;/li>
&lt;li>The web built with ng2, after frontend packaging, had very large volume, making first-screen loading extremely slow. This would definitely be unacceptable for production-level applications.&lt;/li>
&lt;/ul>
&lt;p>The project faced the risk of being killed. I remember that night the company held a meeting to discuss what to do. Facing everyone&amp;rsquo;s technical doubts about the project, I really had nothing to say and felt guilty - was I too aggressive? Also, if the project failed, it would be the company&amp;rsquo;s failure and mine too, since for such relatively large projects, I was already in the architect role. Later we discussed a solution: if compatibility really didn&amp;rsquo;t work, we&amp;rsquo;d prompt users with older browsers to use the old site.&lt;/p>
&lt;p>Once that was done, browser issues at least weren&amp;rsquo;t so severe. Next was performance. ng2 provided lazy loading and AOT compilation solutions, but since the technology was new, actually implementing them wasn&amp;rsquo;t smooth - various errors, various problems.
I remember one day when the project faced reporting - if performance couldn&amp;rsquo;t be solved, it would directly be declared a failure. I really wasn&amp;rsquo;t willing to accept this. At that time, it was really just a little bit left for me. I took pen and paper to analyze.&lt;/p>
&lt;blockquote>
&lt;p>I remember late at night, it was really solved. After AOT succeeded, the entire volume reduced by half. Later adding lazy loading made performance much better. Finally alive! I remember being so excited I couldn&amp;rsquo;t sleep all night, and immediately notified the company leaders.&lt;/p>
&lt;/blockquote>
&lt;p>Later gzip pre-compression, CDN, TSC upgrades, etc. - detailed points. This project constantly faced risks and challenges. I was constantly on the path of discovering problems and solving them. Over time, I actually became an active member of the angular2 expert group, becoming half an expert myself. This group had 1500 people, and reaching that level with ng2 should put me in the top few. Through frequent questioning and communication, several active members became friends, and we separately established another group called angular2 source code analysis group.&lt;/p>
&lt;p>This project was delayed repeatedly until the end of 2016. Of course by then I already had confidence, knowing launch was certain. Everyone was making final development efforts.&lt;/p>
&lt;p>But before this, there was actually a time I planned to give up. I remember texting the CEO saying I&amp;rsquo;d really tried my best, seemed impossible to achieve. But the leader comforted me, saying if you try your best and fail, that&amp;rsquo;s fine, but giving up is wrong. I reflected on what the leader said - yes, I&amp;rsquo;d persisted for a year, so I rallied and continued.&lt;/p>
&lt;p>Facts proved that persistence increases chances of success, while abandonment guarantees failure.&lt;/p>
&lt;h3 id="side-story">
&lt;a class="heading-anchor-link" href="#side-story">Side Story&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="side-story"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Throughout 2016, almost all time was spent exploring and developing the &lt;code>C&lt;/code> project, but I also did a small project in between. If B was the main theme of 2015, then this small project was a side story.&lt;/p>
&lt;p>I remember it was a Wednesday. The leader directly called me over and said a client called asking for such a job - make a display APP, needed quickly. The leader asked how long it would take. I said if we hurry, we could do it in a week. The leader said no - if we start now, can it be done this week? Hearing it needed to be done this week surprised me, but after thinking, I responsibly said yes, we can work overtime to complete it.
I could answer with such confidence because of two points:&lt;/p>
&lt;ol>
&lt;li>I was young, physically I could handle it&lt;/li>
&lt;li>The previous 3 months of comprehensive training had laid the foundation. Simple display APP development didn&amp;rsquo;t need to start from scratch - there was some foundation. Plus this development didn&amp;rsquo;t need backend work - essentially it could be understood as data visualization display&lt;/li>
&lt;/ol>
&lt;p>Based on these two points, I thought it was achievable, so I agreed with the leader. I didn&amp;rsquo;t want to refuse the leader because I wanted to work - it gave me great satisfaction. The leader gave me the client contact&amp;rsquo;s number, saying their backend part and APP requirements would be provided quickly. Just do it.&lt;/p>
&lt;p>So on Wednesday afternoon, I quickly set up the APP framework, then began continuous communication with the client and continuous development. I remember initially working at the company, but due to client data sensitivity and communication inconvenience, I eventually went directly to work at the client&amp;rsquo;s site. Friday, Saturday, Sunday - all three days I slept very late. But seeing partners also working hard, I didn&amp;rsquo;t feel tired. Simultaneously, I realized when we&amp;rsquo;re resting, we rarely think about others constantly working hard. Sooner or later, how could we not be surpassed by others? So around 11 PM Sunday, I finally delivered a version the client was satisfied with, then late at night, everyone took taxis back to sleep.&lt;/p>
&lt;p>Later this project still had multiple small fixes and modifications, but overall it stabilized. Later the leader told me the client called expressing satisfaction with my work. I was happy to hear this, feeling somewhat proud.&lt;/p>
&lt;p>Actually, the smoothness behind this 3.5-day challenge was mainly because of previous similar APPs having ample time for practice, so there were no major issues with existing technology. This gave me the deepest realization: doing things you&amp;rsquo;re already experienced with and good at brings surprisingly high efficiency.&lt;/p>
&lt;h3 id="no-annual-leave">
&lt;a class="heading-anchor-link" href="#no-annual-leave">No Annual Leave&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="no-annual-leave"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>In 2016, I didn&amp;rsquo;t take a single day of annual leave, nor had time to take it. To be precise, many weekends weren&amp;rsquo;t complete - all used for C&amp;rsquo;s development. But now thinking about it, this experience was actually quite good - cultivation. This training is unforgettable, and even in the future, such opportunities aren&amp;rsquo;t common.&lt;/p>
&lt;h2 id="2017">
&lt;a class="heading-anchor-link" href="#2017">2017&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="2017"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="app">
&lt;a class="heading-anchor-link" href="#app">APP&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="app"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>The 2016 C project was huge both technically and in task volume, so it was constantly in development. I remember on January 16th, suddenly the leader called me over saying to go with him to a client to discuss a small project, so I went with the leader.&lt;/p>
&lt;blockquote>
&lt;p>Turns out this client came to us because that previous APP was done well - client A recommended us. Seems this is word-of-mouth reputation.&lt;/p>
&lt;/blockquote>
&lt;p>At the client&amp;rsquo;s side, this was my first time going with the leader to discuss a project face-to-face with a client. Occasionally the client would ask about technical solutions and some details. Due to previous extensive development experience, I was quite comfortable in communication.
Finally it was confirmed doable, but being an emergency project, time was still tight. For me, the additional challenge was that B project also needed continuation - this was essentially extra. &lt;code>Facing this project I was already very skilled at, I really didn't want to give up.&lt;/code>
On the way back I told the leader the project was doable, half laughing at myself as I admitted that after a year of grinding away on project B I had finally started to relax—I’d even booked a ticket home for the 17th (the next day). Clearly I wouldn’t be going anywhere; the coming week had to be dedicated to finishing this app.&lt;/p>
&lt;p>What made this APP different from previous ones was that the backend also needed to be done by us. Of course, since this backend only provided APP data interface services, the difficulty wasn&amp;rsquo;t too great. With previous APP development experience, plus B project&amp;rsquo;s large project architecture and dev experience,
Facing this, I actually had absolute confidence internally.&lt;/p>
&lt;blockquote>
&lt;p>The previous app used Ionic 1, and a quick look at the official site showed that Ionic 2 (built on Angular 2) was already available. Having built project B from scratch and trained heavily in between, I felt confident switching to Ionic 2. Even though I hadn’t used it before, my Ionic 1 and Angular experience meant it wouldn’t be a hurdle. Since the app still needed APIs, I stuck with Express.js for the backend just like project B.&lt;/p>
&lt;/blockquote>
&lt;p>So on the afternoon of the 17th, I quickly did simultaneous frontend-backend development. After a week, I preliminarily completed development and delivered to the client, who expressed great satisfaction with the progress. Then New Year arrived, finally could rest a few days.&lt;/p>
&lt;h3 id="eitheror-choice">
&lt;a class="heading-anchor-link" href="#eitheror-choice">Either/Or Choice?&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="eitheror-choice"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Pre-New Year app work wrapped up smoothly, but none of us expected the torrent of development waiting right after the holiday. Requirements kept shifting—large and small changes arriving at a rapid pace—while the earlier &lt;code>major project C&lt;/code> was still in crunch mode because it hadn’t launched yet. Our timelines collided everywhere.
During this period, a very serious incident occurred - at least I personally considered it serious.
During development I asked someone to help with part of the app. The heavy lifting was already done—I mainly wanted them to gain experience. After a week there was still no progress, and the client even remarked it looked worse than before, pushing the timeline back. I felt guilty; although I knew the helper was out of their depth, it was ultimately my responsibility. I carved out every spare minute to push the app forward while still handling project C. Thankfully my lead and I had already trained a few strong teammates on C, so I could concentrate on the thornier technical issues.&lt;/p>
&lt;p>Even with three heads and six arms, I was stretched too thin and already exhausted. Helpless, I called the CEO and laid out the difficulties. He told me to decide: project C was paramount, and if the app couldn’t be delivered we should drop it and accept the breach.
After hanging up I decided that quitting wasn’t an option. I’d find a way to deliver both. Letting the project fail would harm my reputation, the company, and the client—it simply wasn’t acceptable.&lt;/p>
&lt;p>So I gritted my teeth and persisted. By end of March, the APP was basically finished, finally winning this battle. Although there were some regrets - inadequate service to the client, existing deficiencies. For this I still feel apologetic.&lt;/p>
&lt;h3 id="c-project">
&lt;a class="heading-anchor-link" href="#c-project">C Project+&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="c-project"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Besides this APP in 2017, the most significant was actually the C project and the extended C-GROUP team. Behind the C project was a series of project dev work. The C project, through struggles, finally &lt;code>launched on April Fool's Day&lt;/code>. I joked myself - fool or not fool. On launch day, the team seemed to feel nothing, but I was deeply moved because I knew I had once given up on this project, this project had experienced life and death struggles like me. Thought I could rest a few days, but it seems greater power brings greater responsibility.
Immediately, the company requested a mobile version as soon as possible. At this point, my framework needed adjustment because we couldn&amp;rsquo;t just copy it directly - that would create major maintenance problems in the future. Plus, the web version wasn&amp;rsquo;t comprehensive enough, so we needed to consider how to improve.
Ultimately, I decided to implement a certain degree of reuse. Quickly, within 1-2 months, the mobile version was launched.&lt;/p>
&lt;blockquote>
&lt;p>The client expressed satisfaction with our mobile version launch progress&lt;/p>
&lt;/blockquote>
&lt;p>But the battle wasn&amp;rsquo;t over yet. The derivative projects of C project needed to be completed step by step according to plan - 4 more websites by the end of August. These websites could all be considered similar types, but with differences within the similarities. So for me, I needed to consider refining the project code and improving the project structure.&lt;/p>
&lt;p>How to achieve reuse? After research and analysis, I decided to use git-submodule to organize the code. This means the project itself could use another project as a third-party library.
After some practice, this proved to be a very suitable choice, so development continued this way. As of now, everything is progressing according to the established plan, and the client is satisfied with our development.&lt;/p>
&lt;p>Looking back at all this, I really have many feelings. The people in the team followed the established framework, and when they mentioned difficulties or problems, I tried my best to answer them. But what I really wanted to tell them was &lt;code>problem-solving methods&lt;/code> - how to describe problems, how to find answers, and even how to find mentors.&lt;/p>
&lt;p>Because compared to the difficulties I encountered before, these were actually nothing.&lt;/p>
&lt;h2 id="summary">
&lt;a class="heading-anchor-link" href="#summary">Summary&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="summary"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Unconsciously, I&amp;rsquo;ve written this several-thousand-word journal. This should be my longest blog post, after all it covers 3 years of experiences.
Over these 3 years, I personally believe what these years brought me wasn&amp;rsquo;t just knowledge of node, angular, ionic, java, php, etc., but rather these:&lt;/p>
&lt;ul>
&lt;li>Open-minded thinking&lt;/li>
&lt;li>How to describe problems&lt;/li>
&lt;li>How to find answers&lt;/li>
&lt;li>How to find mentors&lt;/li>
&lt;li>Thinking before acting&lt;/li>
&lt;/ul>
&lt;p>These insights, these understandings, these methods have formed imprints, deeply embedded in my heart, enabling me to continuously improve. As one of my friends said, programming is more about internal skills - thinking is the most important. Once you master thinking and methods, learning anything and doing anything becomes more efficient.&lt;/p>
&lt;hr>
&lt;p>For these understandings, these insights, these improvements, I want to thank these people:&lt;/p>
&lt;h3 id="myself">
&lt;a class="heading-anchor-link" href="#myself">Myself&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="myself"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>First, I thank myself. Over these 3 years, if compared to those who just work normal hours and treat it as a job to earn money for family, I probably put in 5 years worth of effort in 3 years. Because I truly devoted a huge amount of time and consumed countless brain cells. Even for simple problems, I was willing to think about the best implementation methods, and I also wanted to explore why things should be done that way. Because I always demanded of myself to do more, think more, and do things well.
Among these, 2016 was the most exhausting year of the 3 - so exhausting that sometimes I really couldn&amp;rsquo;t go to work and had to reluctantly take a day off. But this experience was truly unforgettable and shaped who I am today.&lt;/p>
&lt;h3 id="ceo">
&lt;a class="heading-anchor-link" href="#ceo">CEO&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ceo"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;code>CEO&lt;/code>, the company&amp;rsquo;s top leader. I clearly understand that even if you&amp;rsquo;re willing to work, you need a stage. Gold doesn&amp;rsquo;t necessarily shine, and the CEO gave me this stage. When you diligently accumulate knowledge and skills, once opportunity comes, you truly take off.&lt;/p>
&lt;p>The APP project gave me a comprehensive opportunity to showcase and unleash my abilities and creativity. In that moment, I felt I could complete a project with high quality and efficiency.&lt;/p>
&lt;p>The 2016 C project enabled me to have ample time to learn, design, and develop.&lt;/p>
&lt;p>Beijing is also a place with many opportunities. There are many conferences like GDD, Microsoft Build, Big Data conferences, etc. All of these were supported by the CEO, giving me opportunities to attend. So many idea collisions enabled me to avoid being closed-minded.&lt;/p>
&lt;h3 id="my-leader">
&lt;a class="heading-anchor-link" href="#my-leader">My Leader&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="my-leader"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;code>Leader Li*&lt;/code>, my first web development project at the company used the framework he built. I sincerely admire it - it&amp;rsquo;s truly high quality. We all need to acknowledge that a good leader is important, just like a good teacher. Also, Li&amp;rsquo;s thinking is very open, actively absorbing external knowledge.
He is my leader, but actually also my friend. Even when I complain to him sometimes, he patiently guides me on what&amp;rsquo;s right and wrong. We worked together to overcome many technical problems and also worked together to change the company, such as promoting gitlab implementation, etc.&lt;/p>
&lt;h3 id="those-online-friends">
&lt;a class="heading-anchor-link" href="#those-online-friends">Those Online Friends&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="those-online-friends"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;blockquote>
&lt;p>For technical work, you first need to use technology. Over these 3 years, I joined no less than 50 QQ groups and countless online friends. Because I was too active, I even became an administrator in several groups, and was mistakenly regarded as a &amp;ldquo;big shot&amp;rdquo; by some unaware friends, etc.
On GitHub, for some open projects like angular, I also became a contributor (just asking questions and communicating, haven&amp;rsquo;t done PRs yet, hehe).&lt;/p>
&lt;/blockquote>
&lt;p>Online friends all help without expecting anything in return. This is the infectious power and strength of open source and openness. So now I also write more technical blog posts, am more active in communities, thus actively helping others. Helping each other this way promotes the development of the entire industry.&lt;/p>
&lt;h2 id="conclusion">
&lt;a class="heading-anchor-link" href="#conclusion">Conclusion&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="conclusion"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>Long articles always have an end. This article is about a programmer constantly struggling and stumbling, walking a path, and narrating the process of walking that path. &lt;strong>The road ahead is long and winding&lt;/strong> - the path of programming has no end because technology changes rapidly, the entire industry is fiercely competitive. If you don&amp;rsquo;t advance, you fall behind. The first 3 years have passed, continue working hard, continue fighting. MARK.&lt;/p>
&lt;p>&lt;figure class="image-figure">
&lt;img
src="https://static.1991421.cn/Octocat.png"
alt="octocat"
loading="lazy"
decoding="async"
class="rounded-lg"
/>
&lt;/figure>&lt;/p></description></item><item><title>NativeScript Explained (Beginner's Guide)</title><link>https://en.1991421.cn/2017/06/11/nativescript/</link><pubDate>Sun, 11 Jun 2017 00:09:57 +0800</pubDate><guid>https://en.1991421.cn/2017/06/11/nativescript/</guid><description>&lt;p>NativeScript is a cross-platform development framework, claiming performance is only 10% worse than native, while also supporting Angular syntax. For those with web and ng development experience, this is quite attractive.&lt;/p>
&lt;h2 id="environment-setup">
&lt;a class="heading-anchor-link" href="#environment-setup">Environment Setup&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="environment-setup"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;h3 id="node-installation">
&lt;a class="heading-anchor-link" href="#node-installation">Node Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="node-installation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>For Node installation, go directly to the official website &lt;a href="https://nodejs.org/zh-cn/download/" target="_blank" rel="noopener">click here&lt;/a>&lt;/p>
&lt;p>Suggestions:&lt;/p>
&lt;ul>
&lt;li>Install nvm to manage multiple Node versions on your machine&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">nvm install node
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nvm use
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>Install nrm, switch registry to Taobao to improve package installation speed&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">$ npm i -g nrm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ nrm ls
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ nrm use taobao //switch registry to taobao
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="install-nativescript-cli">
&lt;a class="heading-anchor-link" href="#install-nativescript-cli">Install NativeScript CLI&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="install-nativescript-cli"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;code>npm install -g nativescript&lt;/code>&lt;/p>
&lt;p>Note: &lt;code>Global installation&lt;/code>&lt;/p>
&lt;h3 id="ios-and-android-environment-installation">
&lt;a class="heading-anchor-link" href="#ios-and-android-environment-installation">iOS and Android Environment Installation&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="ios-and-android-environment-installation"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>Different platforms, different strategies
Follow the official documentation for specific installation details, no need to repeat here&lt;/p>
&lt;ul>
&lt;li>&lt;a href="http://docs.nativescript.org/angular/start/ns-setup-win" target="_blank" rel="noopener">Windows&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://docs.nativescript.org/angular/start/ns-setup-os-x" target="_blank" rel="noopener">Mac&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://docs.nativescript.org/angular/start/ns-setup-linux" target="_blank" rel="noopener">Linux&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Note:&lt;/p>
&lt;ul>
&lt;li>For Android environment, recommend first installing Android Studio, managing SDK through official IDE is more convenient&lt;/li>
&lt;li>If you&amp;rsquo;ve configured Android environment before, corresponding steps can be skipped&lt;/li>
&lt;/ul>
&lt;h3 id="verification-program">
&lt;a class="heading-anchor-link" href="#verification-program">Verification Program&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="verification-program"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;code>tns doctor&lt;/code>&lt;/p>
&lt;h3 id="create-project">
&lt;a class="heading-anchor-link" href="#create-project">Create Project&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="create-project"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;p>&lt;code>tns create HelloWorld --template nativescript-template-ng-tutorial&lt;/code>
Note:
Projects created via template lack &lt;code>App_Resources&lt;/code> resource folder content, so directly running below will report errors. Download from GitHub official demo &lt;a href="https://github.com/NativeScript/nativescript-marketplace-demo/tree/master/app/App_Resources" target="_blank" rel="noopener">click here&lt;/a>, copy folder into project.&lt;/p>
&lt;h3 id="run-project">
&lt;a class="heading-anchor-link" href="#run-project">Run Project&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="run-project"
aria-label="Copy anchor link"
title="Copy anchor link"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">tns run android
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tns run ios
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>At this point, it should be basically OK. Next is to follow the official documentation in detail to learn basic concepts and usage.&lt;/p></description></item><item><title>2016 Year-End Summary</title><link>https://en.1991421.cn/2016/12/31/7973e266/</link><pubDate>Sat, 31 Dec 2016 00:00:00 +0800</pubDate><guid>https://en.1991421.cn/2016/12/31/7973e266/</guid><description>&lt;p>Without realizing it, a year has passed. Looking back at 2016, I suddenly realize I spent almost the whole year on one project - complex, difficult, and huge, so huge that I spent over half a year learning and building it. Rather than the project being too hard, it was me being too weak. I was constantly facing challenges, and &amp;ldquo;walking on thin ice&amp;rdquo; doesn&amp;rsquo;t even feel like an exaggeration. It&amp;rsquo;s my personality and family background - I don&amp;rsquo;t like being vague. So I kept refining and refining until even the client felt it was slow. I made compromises along the way, but now when I look back at the project I poured my heart into, I feel calm, happy, and even teary - a feeling hard to describe. As the project matured and neared launch, I lost that anxiety and learned to handle all kinds of feedback with composure.&lt;/p>
&lt;p>&lt;strong>Time not only polishes a thing, it also shapes a person.&lt;/strong>&lt;/p>
&lt;p>The day-and-night grind all year dragged my body down by more than half (0.1 exaggeration), but every effort still brought a decent return. Now when I look at any &amp;ldquo;elite&amp;rdquo; tech, I no longer feel as I used to. I believe mastering technology requires solid fundamentals, agile thinking, enough diligence, and deep respect for what we do, who we impact, and ourselves.&lt;/p>
&lt;p>This year, I&amp;rsquo;m grateful to those who guided me, supported me, and cared for me.&lt;/p>
&lt;p>For the coming year, I hope to balance work and life and build a healthier rhythm.&lt;/p>
&lt;p>I leave this post to commemorate the difficult and grinding 2016.&lt;/p>
&lt;p>[Share] Everyone needs stage-by-stage self-awakening and awareness: when we look at things, it&amp;rsquo;s not about east or west, but about looking inward. Through constant self-critical thinking, we measure how changes in the people and things around us affect our values, and thus perceive the next stage of ourselves. For most &amp;ldquo;right but useless&amp;rdquo; statements, whether you absorb them depends on mental maturity. Life has no absolute right or wrong, only different angles.&lt;/p></description></item><item><title>Mid‑Year Summary 2016</title><link>https://en.1991421.cn/2016/10/06/49699376/</link><pubDate>Thu, 06 Oct 2016 09:58:37 +0800</pubDate><guid>https://en.1991421.cn/2016/10/06/49699376/</guid><description>&lt;p>More than half of 2015 is gone, and I felt I should write something. This year, I feel I’ve improved a lot technically.
From improving apps to independently developing an app [hybrid], then exploring new tech and independently owning the platform architecture, I took many detours and hit many walls. But after going through it, I truly learned a lot. The more deeply and broadly I learn, the more I realize I’m still a beginner. It’s a frustrating feeling, but it’s also true across all industries.&lt;/p>
&lt;p>This kind of stubborn effort kept me in a high‑pressure, high‑intensity coding state in the first half of the year. Only today do I feel my abilities truly improved—like the naive hero in The Legend of the Condor Heroes finally learning a few moves. Effort pays off; that saying really is true.&lt;/p>
&lt;p>Of course, the barriers I ran into taught me lessons. Youth gives us drive and energy but also inexperience and narrow thinking. That hurt me when doing big or new projects, but it also became a proving ground that helped me grow quickly.&lt;/p>
&lt;p>In short, the road is long and I need to keep pushing. If you think too much and can’t figure it out, stop thinking for now and focus on doing the work at hand.&lt;/p>
&lt;hr>
&lt;p>Here’s a quote I love as a mid‑year encouragement:&lt;/p>
&lt;p>Technology and tools are always just means to realize ideas. Tools can be replaced by better tools, but thinking itself needs constant renewal and improvement.&lt;/p></description></item><item><title>Personal Tech Blog Launched</title><link>https://en.1991421.cn/2016/09/03/38016/</link><pubDate>Sat, 03 Sep 2016 14:31:56 +0800</pubDate><guid>https://en.1991421.cn/2016/09/03/38016/</guid><description>&lt;p>This is my first truly personal site. From now on, I’ll record thoughts and learnings here. I trust my memory, but I trust the pen more.
I graduated in July 2014. Two years flew by; I worked harder than average, comparing myself with those better than me. Abilities improved, and new problems kept appearing. Dissatisfied with the status quo, I kept learning and doing — becoming a little “cockroach” that never stops. Of course, there are always people working harder and doing better. Thanks to them, society improves day by day.
I never cultivated the habit of writing — which is a shame. “No time” is an excuse. If you truly want something, you make time. Thanks to the last two years of steady technical accumulation, this simple site is a small fruit of that effort — and I hope it’s also a seed. May it accompany my journey forward and preserve countless ideas and experiences, for myself and for the Internet from which they came.
I believe excellence is a habit.
The coder’s world is wonderfully curious.&lt;/p></description></item></channel></rss>