Files
swangnice_site/public/index.json
2025-08-18 20:01:21 +08:00

4 lines
69 KiB
JSON
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[{"content":"I hope to share several books about CPU architecture here, and this is a book list:\nComputer Organization and Design RISC-V Edition. David A. Patterson \u0026amp; John L. Hennessy Computer Architecture: A Quantitative Approach. John L. Hennessy \u0026amp; David A. Patterson Additionally, I plan to create CPU demonstrations using Verilog/SystemVerilog.\n","date":"20 September 2024","externalUrl":null,"permalink":"/notes/mcu/cpu_architecture_notes/","section":"Notes","summary":"\u003cp\u003eI hope to share several books about CPU architecture here, and this is a book list:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eComputer Organization and Design RISC-V Edition. \u003cem\u003eDavid A. Patterson \u0026amp; John L. Hennessy\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003eComputer Architecture: A Quantitative Approach. \u003cem\u003eJohn L. Hennessy \u0026amp; David A. Patterson\u003c/em\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eAdditionally, I plan to create CPU demonstrations using Verilog/SystemVerilog.\u003c/p\u003e","title":"Notes on CPU Architecture","type":"notes"},{"content":"For my first physical server in my life, I got an Mac Mini with M4 and an HDD enclosure.\n","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/mac_mini_m4/","section":"Projects","summary":"\u003cp\u003eFor my first physical server in my life, I got an Mac Mini with M4 and an HDD enclosure.\u003c/p\u003e","title":"My First Server in Room: Mac Mini + SSD Enclosure","type":"projects"},{"content":"This is a bot that assists in making daily index fund trading decisions.\nIntroduction # This project was inspired by my mother. Over the course of ten years, she watched my father struggle in the stock market. From those hard lessons, she developed her own strategy—one that focuses on the predictable fluctuations in index fund values. Armed with nothing more than paper, a pen, and a calculator, shes been able to achieve steady profits.\nI believe theres even more potential here.\nBy digitizing her process and gradually introducing quantifiable algorithms, I hope to both increase efficiency and explore new edges for profitability. My strategy might cause others\u0026rsquo; losses, so this project is private permanently.\nList # Here, Ill keep track of the to-do list and showcase the results as the project evolves. Ill also highlight some interesting technical insights along the way.\n","date":"20 September 2024","externalUrl":null,"permalink":"/zh-cn/projects/self_host/stock_bot/","section":"Projects","summary":"\u003cp\u003eThis is a bot that assists in making daily index fund trading decisions.\u003c/p\u003e\n\n\n\u003ch2 class=\"relative group\"\u003eIntroduction \n \u003cdiv id=\"introduction\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#introduction\" aria-label=\"锚点\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eThis project was inspired by my mother. Over the course of ten years, she watched my father struggle in the stock market. From those hard lessons, she developed her own strategy—one that focuses on the predictable fluctuations in index fund values. Armed with nothing more than paper, a pen, and a calculator, shes been able to achieve steady profits.\u003c/p\u003e","title":"StockBot","type":"projects"},{"content":" Short-term TODO # 🚧 The Initial Policy implement (Parameterizing transaction variables) ⬜️ The evaluate \u0026amp; logger script ⬜ The automatic scripts with Email Sender deployed on the Server ⬜ Web UI, will not be too complex just a simple one to synchronous my account for customized policy ⬜️ Implement RL algorithms ","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/stock_bot/01_todo/","section":"Projects","summary":"\u003ch2 class=\"relative group\"\u003eShort-term TODO \n \u003cdiv id=\"short-term-todo\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#short-term-todo\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e🚧 The Initial Policy implement (Parameterizing transaction variables)\u003c/li\u003e\n\u003cli\u003e⬜ The evaluate \u0026amp; logger script\u003c/li\u003e\n\u003cli\u003e⬜ The automatic scripts with Email Sender deployed on the Server\u003c/li\u003e\n\u003cli\u003e⬜ Web UI, will not be too complex just a simple one to synchronous my account for customized policy\u003c/li\u003e\n\u003cli\u003e⬜ Implement RL algorithms\u003c/li\u003e\n\u003c/ul\u003e","title":"TODO List","type":"projects"},{"content":"I don\u0026rsquo;t have a public IP, so my solution is SSH tunnel + reverse Proxy on cloud server.\n🍎Mac Mini Side # As a server, my Mac won\u0026rsquo;t sleep, so change the setting firstly.\nsudo systemsetup -setcomputersleep Never # never sleep sudo systemsetup -setdisplaysleep 10 # display will sleep in 10 min Use autossh to avoid timeout:\nbrew install autossh Add the configuration below in ~/.ssh/config Mac Mini will send package per 30 seconds to keep the connection alive.\nHost \u0026lt;ip address\u0026gt; ServerAliveInterval 30 ServerAliveCountMax 5 TCPKeepAlive yes Build the connection:\nautossh -M 0 -f -N \\ -i ~/.ssh/id_ed25519 \\ -o \u0026#34;ServerAliveInterval 30\u0026#34; -o \u0026#34;ServerAliveCountMax 3\u0026#34; \\ -R 0.0.0.0:9000:localhost:1313 \\ root@\u0026lt;ip address\u0026gt; autossh -M 0 -f -N -o \u0026#34;ServerAliveInterval 30\u0026#34; -o \u0026#34;ServerAliveCountMax 3\u0026#34; -R 0.0.0.0:9000:localhost:1313 user@\u0026lt;your.server.com\u0026gt; A watchdog script to try reconnection when the network lost(add to LaunchAgent):\n#!/bin/bash while true; do ping -c 1 \u0026lt;ip address\u0026gt; \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 if [ $? -ne 0 ]; then pkill -f autossh autossh -M 0 -f -N -R 0.0.0.0:1313:localhost:1313 \u0026lt;ip address\u0026gt; fi sleep 60 done 💻Server Side # Install and config the Nginx, for me the config file in /etc/nginx/sites-available:\nserver { listen 80; server_name www.\u0026lt;your domain\u0026gt; \u0026lt;your domain\u0026gt;; location / { proxy_pass http://localhost:1313; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } Then, link the config file to sites-enabled, check and reload the Nginx configuration:\nln -s /etc/nginx/sites-available/\u0026lt;your config file\u0026gt; /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx To obtain a security certificate, use the certbot:\nsudo apt update sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d swangnice.cn ","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/mac_mini_m4/01_website_hosting/","section":"Projects","summary":"\u003cp\u003eI don\u0026rsquo;t have a public IP, so my solution is SSH tunnel + reverse Proxy on cloud server.\u003c/p\u003e\n\n\n\u003ch2 class=\"relative group\"\u003e🍎Mac Mini Side \n \u003cdiv id=\"mac-mini-side\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#mac-mini-side\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eAs a server, my Mac won\u0026rsquo;t sleep, so change the setting firstly.\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esudo systemsetup -setcomputersleep Never # never sleep\nsudo systemsetup -setdisplaysleep 10 # display will sleep in 10 min\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eUse autossh to avoid timeout:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ebrew install autossh\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eAdd the configuration below in \u003ccode\u003e~/.ssh/config\u003c/code\u003e Mac Mini will send package per 30 seconds to keep the connection alive.\u003c/p\u003e","title":"Website Setup","type":"projects"},{"content":" Hardware # I went with the UNITEK 3373BBK for one of my drive enclosures—and honestly, it wasnt the best decision.\nThe first big letdown? The bandwidth tops out at just 5Gbps. Thats fine for basic tasks, but definitely underwhelming if youre dealing with high-speed storage or large file transfers.\nEven worse, it doesnt support S.M.A.R.T passthrough, which makes monitoring drive health a hassle. That was a big deal-breaker for me.\nStill, none of the other options really fit my expectations either. One day, I might just go all-in and make my own enclosure—design the PCB, write the firmware, the whole deal. Maybe not today… but someday.\ndiskutil list diskutil list\nsudo smartctl -a /dev/disk2 brew install smartmontools\n","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/mac_mini_m4/02_nas/","section":"Projects","summary":"\u003ch2 class=\"relative group\"\u003eHardware \n \u003cdiv id=\"hardware\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#hardware\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eI went with the UNITEK 3373BBK for one of my drive enclosures—and honestly, it wasnt the best decision.\u003c/p\u003e\n\u003cp\u003eThe first big letdown? The bandwidth tops out at just 5Gbps. Thats fine for basic tasks, but definitely underwhelming if youre dealing with high-speed storage or large file transfers.\u003c/p\u003e\n\u003cp\u003eEven worse, it doesnt support S.M.A.R.T passthrough, which makes monitoring drive health a hassle. That was a big deal-breaker for me.\u003c/p\u003e","title":"NAS: Network Attachment Storage","type":"projects"},{"content":"This section will feature occasional showcases of my technical achievements—focused purely on the engineering side, not the income.\n","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/stock_bot/02_results/","section":"Projects","summary":"\u003cp\u003eThis section will feature occasional showcases of my technical achievements—focused purely on the engineering side, not the income.\u003c/p\u003e","title":"Showcases","type":"projects"},{"content":"Install dependence of gitea:\nbrew install git brew install gitea The database # Install MySQL:\nbrew install mysql brew services start mysql Login MySQL and create the database and user:\nmysql -u root Then, execute:\nCREATE DATABASE gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER \u0026#39;gitea\u0026#39;@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;\u0026lt;yourpassword\u0026gt;\u0026#39;; GRANT ALL PRIVILEGES ON gitea.* TO \u0026#39;gitea\u0026#39;@\u0026#39;localhost\u0026#39;; FLUSH PRIVILEGES; Config the Gitea # Start the configuration page of Gitea:\ngitea web After filling all information it required, it will generate a config file, for me, it\u0026rsquo;s in/opt/homebrew/var/gitea/custom/conf/app.ini, then you can configure more details in this file. I strongly recommend close the public registration.\n🚫outdated \u0026ndash; Use autossh to build the new connection\nautossh -M 0 -f -N \\ -i ~/.ssh/id_ed25519 \\ -o \u0026#34;ServerAliveInterval 30\u0026#34; -o \u0026#34;ServerAliveCountMax 3\u0026#34; \\ -R 127.0.0.1:3000:localhost:3000 \\ -R 127.0.0.1:9000:localhost:1313 \\ root@\u0026lt;ip_address\u0026gt; ✅ Now I wrote a script to keep the connection alive, it contains some sensitive info like IP and ports, so I will not share it here.\n","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/mac_mini_m4/03_gitea/","section":"Projects","summary":"\u003cp\u003eInstall dependence of gitea:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ebrew install git\nbrew install gitea\n\u003c/code\u003e\u003c/pre\u003e\n\n\u003ch2 class=\"relative group\"\u003eThe database \n \u003cdiv id=\"the-database\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#the-database\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eInstall MySQL:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ebrew install mysql\nbrew services start mysql\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eLogin MySQL and create the database and user:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003emysql -u root\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThen, execute:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eCREATE DATABASE gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;\nCREATE USER \u0026#39;gitea\u0026#39;@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;\u0026lt;yourpassword\u0026gt;\u0026#39;;\nGRANT ALL PRIVILEGES ON gitea.* TO \u0026#39;gitea\u0026#39;@\u0026#39;localhost\u0026#39;;\nFLUSH PRIVILEGES;\n\u003c/code\u003e\u003c/pre\u003e\n\n\u003ch2 class=\"relative group\"\u003eConfig the Gitea \n \u003cdiv id=\"config-the-gitea\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#config-the-gitea\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eStart the configuration page of Gitea:\u003c/p\u003e","title":"My Own Code Vault: Gitea on Mac Mini","type":"projects"},{"content":" swangnice/mcu-benchmark A markbench of MCUs to help to you choose the right one. Python 0 0 This is a personal project to benchmark various MCUs (Microcontroller Units) using FastAPI and SQLite for the backend and Vue.js for the frontend. The project allows you to add, list, and compare different MCUs.\nYou can access the project at HERE.\nmcubenchmark/ ├── backend/ │ ├── main.py # FastAPI Entrance │ ├── database.py # SQLite Base operations │ ├── admin.py # SQLite CURD │ └── mcu.db ├── frontend/ │ ├── public/ │ ├── src/ │ │ ├── views/ │ │ │ ├── ListView.vue │ │ │ ├── DetailView.vue │ │ │ └── CompareView.vue │ │ ├── App.vue │ │ └── main.js ├── README.md └── requirements.txt How to use? # Clone this repo, and install the requirements:\ncd mcu-benchmark conda create -n mcu-benchmark conda activate mcu-benchmark pip install -r requirements.txt Then, start the backend server:\ncd backend uvicorn main:app --host 0.0.0.0 --port 3010 --reload Use admin.py and follow the instructions to add MCUs to the database:\npython admin.py Now, you can access the backend API at http://localhost:3010/api/mcus.\nRun the frontend (before this step, you need to install Node.js, npm and other dependencies):\ncd backend npm run dev Now, you can access the frontend at http://localhost:\u0026lt;port\u0026gt;. The default port of Vite is 5173.\n","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/mac_mini_m4/04_mcu_markbench/","section":"Projects","summary":"\u003ca id=\"gitea-557b8590fb1ca3d7d5e6d0761887bbe0\" target=\"_blank\" href=\"https://code.swangnice.cn/swangnice/mcu-benchmark\" class=\"cursor-pointer\"\u003e\n \u003cdiv\n class=\"w-full md:w-auto pt-3 p-5 border border-neutral-200 dark:border-neutral-700 border rounded-md shadow-2xl\"\u003e\n\n \u003cdiv class=\"flex items-center\"\u003e\n \u003cspan class=\"text-2xl text-neutral-800 dark:text-neutral\" style=\"margin-right:10px;\"\u003e\n \n\n \u003cspan class=\"relative block icon\"\u003e\n \u003csvg xmlns=\"http://www.w3.org/2000/svg\" xml:space=\"preserve\" viewBox=\"5.67 143.05 628.65 387.55\"\u003e\u003cpath fill=\"currentColor\" d=\"M115.912 143.075c-6.462 0-13.762.525-22.012 2.325-8.7 1.8-33.5 7.4-53.8 26.9C-4.9 212.4 6.6 276.2 8 285.8c1.7 11.7 6.9 44.2 31.7 72.5 45.8 56.1 144.4 54.8 144.4 54.8s12.1 28.9 30.6 55.5c25 33.1 50.7 58.9 75.7 62 63 0 188.9-.1 188.9-.1s12 .1 28.3-10.3c14-8.5 26.5-23.4 26.5-23.4S547 483 565 451.5c5.5-9.7 10.1-19.1 14.1-28 0 0 55.2-117.1 55.2-231.1-1.1-34.5-9.6-40.6-11.6-42.6-4.1-4.1-9.6-4-9.6-4s-117.2 6.6-177.9 8c-13.267.3-26.433.597-39.5.697l.1 117.002s57.4 24.202 83.1 40.102c3.7 2.3 10.2 6.798 12.9 14.398 2.1 6.1 2 13.101-1 19.301l-61 126.9c-6.2 12.7-21.4 18.1-33.9 12l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5 21.2-17.9 33.8-11.8a5290.322 5290.322 0 0 0 27 12.954c0-36.449-.1-109.053-.1-109.053-29 .4-89.2-2.201-89.2-2.201s-141.4-7.1-156.8-8.5c-4.9-.3-10.525-.825-16.988-.825zm12.188 48.026s7.1 59.399 15.7 94.199c7.2 29.2 24.8 77.7 24.8 77.7s-26.1-3.1-43-9.1c-25.9-8.5-36.9-18.7-36.9-18.7S69.6 321.8 60 295.4c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5 38.5-30c13.8-3.7 31-3.1 31-3.1z\"/\u003e\u003cpath fill=\"currentColor\" d=\"M326.8 380.1c-8.2.1-15.4 5.8-17.3 13.8-1.9 8 2 16.3 9.1 20 7.7 4 17.5 1.8 22.7-5.4 5.1-7.1 4.3-16.9-1.8-23.1l24-49.1c1.5.1 3.7.2 6.2-.5 4.1-.9 7.1-3.6 7.1-3.6 4.2 1.8 8.6 3.8 13.2 6.1 4.8 2.4 9.3 4.9 13.4 7.3.9.5 1.8 1.1 2.8 1.9 1.6 1.3 3.4 3.1 4.7 5.5 1.9 5.5-1.9 14.9-1.9 14.9-2.3 7.6-18.4 40.6-18.4 40.6-8.1-.2-15.3 5-17.7 12.5-2.6 8.1 1.1 17.3 8.9 21.3 7.8 4 17.4 1.7 22.5-5.3 5-6.8 4.6-16.3-1.1-22.6 1.9-3.7 3.7-7.4 5.6-11.3 5-10.4 13.5-30.4 13.5-30.4.9-1.7 5.7-10.3 2.7-21.3-2.5-11.4-12.6-16.7-12.6-16.7-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3 4.7-9.7 9.4-19.3 14.1-29-4.1-2-8.1-4-12.2-6.1-4.8 9.8-9.7 19.7-14.5 29.5-6.7-.1-12.9 3.5-16.1 9.4-3.4 6.3-2.7 14.1 1.9 19.8l-24.6 50.4z\"/\u003e\u003c/svg\u003e\n \u003c/span\u003e\n\n\n \u003c/span\u003e\n \u003cdiv\n id=\"gitea-557b8590fb1ca3d7d5e6d0761887bbe0-full_name\"\n class=\"m-0 font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral\"\u003e\n swangnice/mcu-benchmark\n \u003c/div\u003e\n \u003c/div\u003e\n\n \u003cp id=\"gitea-557b8590fb1ca3d7d5e6d0761887bbe0-description\" class=\"m-0 mt-2 text-md text-neutral-800 dark:text-neutral\"\u003e\n A markbench of MCUs to help to you choose the right one.\n \u003c/p\u003e","title":"MCU Benchmark","type":"projects"},{"content":"PDFding is a self-hosted PDF library management system, which is perfect for managing my personal PDF collection. It allows me to organize, search, and read PDFs directly from my Mac Mini. Later I will list a contents of my PDF library, if you need any of them, just email me. No commercial use, please.\nInstall Docker and Prepare Directories # Download Docker Desktop, and install it.\nmkdir -p \u0026lt;where you like\u0026gt;/pdfding/{data,media} chmod a+w \u0026lt;where you like\u0026gt;/pdfding/{data,media} cd \u0026lt;where you like\u0026gt;/pdfding/ data is used to store the database, media is used to store the PDF files.\nBuild the Container # docker run --name pdfding \\ -p \u0026lt;port\u0026gt;:\u0026lt;port\u0026gt; \\ -v ./db:/home/nonroot/pdfding/db -v ./media:/home/nonroot/pdfding/media \\ -e HOST_NAME=127.0.0.1,\u0026lt;your_domain\u0026gt; -e SECRET_KEY=\u0026lt;you_key\u0026gt; -e CSRF_COOKIE_SECURE=FALSE -e SESSION_COOKIE_SECURE=FALSE \\ -d \\ mrmn/pdfding:latest Then, you should be able to access the PDFding web interface at http://localhost:\u0026lt;port\u0026gt;.\nCreate an Account and Disable Registration # If it\u0026rsquo;s your first time using PDFding, you will need to create an account. After that, I strongly recommend disabling the public registration to prevent unauthorized access. You can do this by editing the /home/nonroot/pdfding/users/views.py file in the container.\ndocker cp pdfding:/home/nonroot/pdfding/users/views.py ./views.py Then, find a function named PdfDingSignupView, change it:\nfrom django.http import HttpResponseForbidden @method_decorator(login_not_required, name=\u0026#34;dispatch\u0026#34;) class PdfDingSignupView(SignupView): \u0026#34;\u0026#34;\u0026#34; Overwrite allauths signup to be accessed without being logged in \u0026#34;\u0026#34;\u0026#34; @login_not_required def dispatch(self, request, *args, **kwargs): #return super(PdfDingSignupView, self).dispatch(request, *args, **kwargs) return HttpResponseForbidden(\u0026#34;Registration is disabled by the administrator.\u0026#34;) Then, copy it back to the container:\ndocker cp ./views.py pdfding:/home/nonroot/pdfding/users/views.py Finally, restart the container:\ndocker restart pdfding ","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/mac_mini_m4/05_pdf_shelf/","section":"Projects","summary":"\u003cp\u003ePDFding is a self-hosted PDF library management system, which is perfect for managing my personal PDF collection. It allows me to organize, search, and read PDFs directly from my Mac Mini. Later I will list a contents of my PDF library, if you need any of them, just email me. No commercial use, please.\u003c/p\u003e\n\n\n\u003ch2 class=\"relative group\"\u003eInstall Docker and Prepare Directories \n \u003cdiv id=\"install-docker-and-prepare-directories\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#install-docker-and-prepare-directories\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eDownload \u003ca href=\"https://www.docker.com/products/docker-desktop/\" target=\"_blank\"\u003eDocker Desktop\u003c/a\u003e, and install it.\u003c/p\u003e","title":"My Own PDF Shelf: pdfding on Mac Mini","type":"projects"},{"content":"Immich is a self-hosted photo and video management solution that allows you to organize, share, and access your media files from anywhere. It provides features like automatic backups, facial recognition, and easy sharing options.\nInstallation # Follow the official Immich installation guide for detailed instructions. Below is a quick overview of the steps to get started.\ncd \u0026lt;where you like\u0026gt; mkdir ./immich-app cd ./immich-app wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env cp example.env .env Edit the .env file to set your desired configuration options, such as database settings and server URLs. Make sure to set the APP_URL to your server\u0026rsquo;s URL.\nThen, run the following command to start Immich:\ndocker compose up -d Then Enjoy!!!\nQuote Photos in Hugo page # Share the photo using Immich. Navigate to Sharing \u0026gt; Shared links and select the tab corresponding to your shared content. Open the web developer tools by pressing F12, then click on the photo you wish to quote. In the Network tab, locate the request that displays the image preview and copy the URL. This URL should resemble https://your-immich-domain.cn/api/assets/xxxxxxxxx/thumbnail?key=xxxxxxxxxxx=preview\u0026amp;c=xxxxxxxxx. ","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/mac_mini_m4/06_photo_server/","section":"Projects","summary":"\u003cp\u003eImmich is a self-hosted photo and video management solution that allows you to organize, share, and access your media files from anywhere. It provides features like automatic backups, facial recognition, and easy sharing options.\u003c/p\u003e\n\n\n\u003ch2 class=\"relative group\"\u003eInstallation \n \u003cdiv id=\"installation\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#installation\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eFollow the official \u003ca href=\"https://immich.app/docs/overview/quick-start\" target=\"_blank\"\u003eImmich installation guide\u003c/a\u003e for detailed instructions. Below is a quick overview of the steps to get started.\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ecd \u0026lt;where you like\u0026gt;\nmkdir ./immich-app\ncd ./immich-app\nwget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml\nwget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env\ncp example.env .env\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eEdit the \u003ccode\u003e.env\u003c/code\u003e file to set your desired configuration options, such as database settings and server URLs. Make sure to set the \u003ccode\u003eAPP_URL\u003c/code\u003e to your server\u0026rsquo;s URL.\u003c/p\u003e","title":"My Own Photo Server: Immich on Mac Mini","type":"projects"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/notes/coding/","section":"Notes","summary":"","title":"Coding","type":"notes"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/projects/embedded/","section":"Projects","summary":"","title":"Fancy Things on Boards","type":"projects"},{"content":"Ive recently been exploring the world of self-hosted solutions, and its nothing short of amazing. There are some great collections out there that showcase powerful, privacy-respecting tools you can run on your own hardware:\nA collection on GitHub selfh.st ❓ Why Self-Host? # I enjoy automating tasks and making my life smarter with scripts and small tools. Having control over the services I use, running them on my own hardware, and customizing everything to suit my needs—its both empowering and educational.\nIll use this space to document the projects I build and share what I learn along the way.\nList # ","date":"20 September 2024","externalUrl":null,"permalink":"/projects/self_host/","section":"Projects","summary":"\u003cp\u003eIve recently been exploring the world of self-hosted solutions, and its nothing short of amazing. There are some great collections out there that showcase powerful, privacy-respecting tools you can run on your own hardware:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/awesome-selfhosted/awesome-selfhosted\" target=\"_blank\"\u003eA collection on GitHub\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://selfh.st/\" target=\"_blank\"\u003eselfh.st\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\n\u003ch2 class=\"relative group\"\u003e❓ Why Self-Host? \n \u003cdiv id=\"-why-self-host\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#-why-self-host\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eI enjoy automating tasks and making my life smarter with scripts and small tools. Having control over the services I use, running them on my own hardware, and customizing everything to suit my needs—its both empowering and educational.\u003c/p\u003e","title":"Self-host Projects","type":"projects"},{"content":"Here are some insights from my experiences with MCUs. Additionally, you can find my personal MCU benchmark site here.\nAdditionally, I know several excellent books about CPU architecture and plan to share a series of notes based on them.\n","date":"20 September 2024","externalUrl":null,"permalink":"/notes/mcu/","section":"Notes","summary":"\u003cp\u003eHere are some insights from my experiences with MCUs. Additionally, you can find my personal MCU benchmark site \u003ca href=\"https://mcubenchmark.swangnice.cn\" target=\"_blank\"\u003ehere\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eAdditionally, I know several excellent books about CPU architecture and plan to share a series of notes based on them.\u003c/p\u003e","title":"MCU's Story","type":"notes"},{"content":"I have created a PDF collection (PDFDing) for individual PDF files primarily for personal use. Additionally, I will share my personal notes in PDF format. The theme I am using does not support Ketax well (it renders slowly on poor connections), and since my notes contain many equations, PDF is the best option. I plan to upload my notes on a weekly or monthly basis. Here are the details:\nHandwritten # ","date":"20 September 2024","externalUrl":null,"permalink":"/notes/pdf/","section":"Notes","summary":"\u003cp\u003eI have created a PDF collection (\u003ca href=\"/projects/self_host/mac_mini_m4/05_pdf_shelf\"\u003ePDFDing\u003c/a\u003e) for individual PDF files primarily for personal use. Additionally, I will share my personal notes in PDF format. The theme I am using does not support Ketax well (it renders slowly on poor connections), and since my notes contain many equations, PDF is the best option. I plan to upload my notes on a weekly or monthly basis. Here are the details:\u003c/p\u003e\n\n\n\u003ch2 class=\"relative group\"\u003eHandwritten \n \u003cdiv id=\"handwritten\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#handwritten\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e","title":"PDF Collection","type":"notes"},{"content":" 1. Project Photos \u0026amp; Screenshots # The final project photo. The standalone PCBA, top. The standalone PCBA, bottom. Thermal camera images while the board is running under load. The Altium Board design in 2D view. The Altium Board design in 3D view. Node-RED dashboard Node-RED backend Block diagram of the system. 2. Project Summary # Device Description # SG90 Servo Motor\nThe servo motor is used to turn on and off the food storage. It is much more complicated than we expected when we implemented the drivers by ourselves. Since the rotation of the servo angle is controlled by the PWM signals which are generated by the TCC/TC timer counter, not all MCU pins are attached to this function. Fortunately, the pin PA11 we assigned has the TCC1 counter. After the successful generation of the PWM signal, the next problem is how to verify the duty cycle after the system initialization. Once we change the compare_match in the tcc_configure process, the whole system will get stuck and cashed. We solved it by using the tcc_set_compare_value function, where we can change the PWM length by calculating the required timer counter ticks based on the datasheet parameters.\nLoad Cell with NAU7802 ADC\nThe load cell is used to measure the weight data and the ADC is used to convert the raw data to the real value, which is communicated with the MCU through the I2C protocol. The problem with this device is that there are numerous registers in the datasheet, which is necessary to find out how to assign them correctly. This is the essential part of the ADC chip working because the wrong initialization of the registers will lead to the unsuccessful value read. After figuring out the correct presetting of the ADC, the calibration and handling of raw data is also a huge problem. In the end, though the real weight converting is still not so accurate, we at least can measure the load cell value with the correct tendency.\nST7735 LCD TFT Screen\nThe LCD screen is used to display the weight data measured from the load cell, which is connected to the SAMW25 chip by SPI communication. Although we learned the basic initialization and LCD function in the ESE5190 class last semester, we still met unexpected problems in SPI configuration. The SCK and MOSI pins must be under the same SERCOM, and need to be defined with the CONF_MASTER_PINMUX_PAD.\nInternet Augment\nEnable users to control and monitor the device remotely through a web or mobile application. This could involve turning devices on/off(SG90 motor), adjusting settings, or receiving real-time data updates from sensors(load cell). Utilize cloud services to store data collected by the device. This data can then be analyzed to provide insights, trends, or predictive maintenance alerts. Cloud platforms like AWS, Google Cloud, or Microsoft Azure(used in this project) offer various tools for data storage, processing, and analysis. Implement FOTA capabilities to remotely update device firmware. This ensures that devices can receive bug fixes, security patches, or new features without requiring physical access or manual intervention.\nInspiration # The project is inspired by my friend who has a cute but hungry cat. We need to feed it two or three times per day, but we are very busy studying on campus. Therefore, we want to design a pet feeder that can provide food for the cat at home while we are studying in school.\nRemote Feeding: Create a system that allows pet owners to feed their pets remotely using a mobile app or web interface. This could be particularly useful for pet owners who are away from home for extended periods. Scheduled Feeding: Implement scheduling functionality that enables pet owners to set specific times for automatic feeding. This ensures that pets receive their meals on time, even when their owners are busy or away. Portion Control: Incorporate portion control features that allow pet owners to dispense precise amounts of food for each feeding. This helps prevent overfeeding or underfeeding and ensures that pets receive the appropriate amount of nutrition. Customizable Diet Plans: Provide pet owners with the ability to create customized diet plans tailored to their pets\u0026rsquo; specific dietary needs and preferences. This could involve setting different portion sizes or types of food for each meal. Food Monitoring: Integrate sensors or cameras to monitor food levels in the feeder and send alerts when it\u0026rsquo;s time to refill. This helps ensure that pets always have access to food and prevents them from going hungry. Device Functionality # The device operation logic is described as follows: The user can press the servo button on the website to control the on/off food storage. Once the food is dropped, the load cell will measure the weight data and upload it to the cloud and process, which is visible on the website. Also, the weight information will be sent to the LCD screen to show the total weight of the food.\nChallenges # We encountered a lot of unexpected problems on this project both in hardware and software.\nWe want to use the TCC timer counter to generate the PWM signal, but we met the problem that once the timer counter compare match value is set in system initialization, it is hard to modify later to change the rotation angle of the motor. We solved it by using the tcc_set_compare_value function. Initially, we prepared to use an ultrasonic distance sensor HC-SR04 to detect the location of the pets. We previously thought that this sensor simply needs two GPIO to control, but it needs the trig and echo pin applied with the PWM signals. Unfortunately, the pins we assigned for the trig and echo pins have no TCC counter attached, which cannot support the PWM signal generation. So we cancel this sensor in the end. We met the design problem of connecting the I2C pins SCL and SDA in the wrong direction, and I attached the SCL signal to the PA08 and the SDA signal to the PA09. I first wanted to change the codes to solve this problem, but we found that it was hard to achieve since all the pin functions are set as the starter project. Finally, it was solved by disconnecting the I2C jumpers and resoldering the correct connections to make the I2C device work. Prototype Learnings # We gained extensive knowledge about testing methodologies, testing from the specific region to the entire system. We first tested the function of two power regulators, first testing the boost converter, and then the buck converter. After making sure both the converters are outputting the correct voltage, we tested the whole power module is working. We implemented lots of 0Ohm resistors as jump wires, which proved instrumental in facilitating the measurement of various system components\u0026rsquo; performance, particularly those that had not been previously explored. Our exposure to standardized testing methodologies has furnished us with invaluable insights and skills that will prove beneficial in our future endeavors. If given the chance to redesign, we might opt to swap out the 0805 packages with the 0603 as it offers better accessibility for measurement purposes. Alternatively, we could incorporate additional test points into the design. Additionally, we aspire to refine the board\u0026rsquo;s layout to make it more compact and increase its density. Next Steps # We can add more useful functions to the project, such as including a motor driver(DRV8801/DRV8803) to control the water pump, which can provide the pet with not only food but also water to drink. We can implement the feedback control algorithm to add another feeding mode that always fills the food with the fixed value, which will provide the pet the enough food to eat. Takeaways from ESE5160 # We acquired a wealth of invaluable knowledge throughout our project journey. From the intricacies of PCBA design to the intricacies of programming and firmware uploading, each step presented its own set of challenges and learning opportunities. Notably, we gained significant insights into PCB design and the utilization of FreeRTOS. Additionally, we deepened our understanding of I2C and SPI protocols, which honed our skills in unit testing and debug-thinking, further enriching our learning experience.\nProject links # The Node-RED instance link:\nhttp://68.154.49.115:1880/ui/#!/0?socketid=DRc2CLKWRofETc06AAAW\nThe code repository link:\nhttps://github.com/ese5160/a12g-firmware-drivers-t19-pet-feeder/tree/main/Final_submission\nThe Altium 365 link:\nhttps://upenn-eselabs.365.altium.com/designs/EA1CCED6-8C54-4405-B127-DA898DF3EFB7#design\n3. Hardware \u0026amp; Software Requirements # Hardware Requirements # Overview of Hardware Components:\nThe hardware aspect of the project comprised several components including the SAMW25 MCU, load cells, ultrasonic distance sensor, servo motor, and LCD display. Description of Components:\nEach component was carefully selected and described in detail, specifying its functionality, datasheet references, and purpose within the project. The load cells were intended to measure food weight, while the ultrasonic distance sensor aimed to detect the pet\u0026rsquo;s position. The servo motor controlled the food release mechanism, and the LCD display provided real-time information. Functionality:\nMost hardware components, such as the load cells, servo motor, and LCD display, operated as intended and aligned with the project\u0026rsquo;s specifications. However, the distance sensor encountered issues, failing to accurately measure distance or provide reliable data regarding pet position. Potential Causes of Sensor Failure: The failure of the distance sensor was attributed to hardware malfunction: incorrect wiring with compatibility issues with the MCU. Mitigation Steps Taken: Throughout the semester, efforts were made to troubleshoot and resolve the issue with the distance sensor, including checking connections, reconfiguring setups, and reviewing software implementations. Outcome: Despite troubleshooting attempts, the distance sensor remained non-functional by the end of the semester, posing a notable challenge to the project\u0026rsquo;s completeness. Software Requirements # Overview of Software Architecture:\nThe software aspect of the project operated in two parts: one on the MCU for data processing and actuation, and the other on the cloud or MCU acting as a web server for user interaction. MQTT facilitated communication between these two parts. Functionality:\nThe software fulfilled specified functionalities outlined in the Software Requirements Specification (SRS), including bootloader initialization, main loop operation, sensor data handling, actuator control, LCD display, MQTT configuration, and web app features. User Interface:\nThe web app provided a user-friendly interface accessible via phone or laptop, displaying machine/environment status and offering buttons for sending instructions. Integration with Hardware:\nThe software successfully integrated with hardware components, collecting data from sensors, operating actuators based on certain conditions, and receiving messages through MQTT. Testing and Validation:\nThroughout development, rigorous testing and validation procedures were implemented to ensure software functionalities operated as intended and aligned with project requirements. Outcome:\nDespite challenges with the distance sensor, the software aspect of the project functioned effectively, meeting user needs and providing a seamless interaction experience. In conclusion, while the hardware aspect faced challenges with the distance sensor, the software aspect operated successfully, fulfilling specified requirements and ensuring the project\u0026rsquo;s overall functionality and usability.\n","date":"20 September 2024","externalUrl":null,"permalink":"/projects/embedded/pet_feeder/","section":"Projects","summary":"\u003c!-- - [1. Video Presentation](#1-video-presentation)\n- [2. Project Summary](#2-project-summary)\n - [Device Description](#device-description)\n - [Inspiration](#inspiration)\n - [Device Functionality](#device-functionality)\n - [Challenges](#challenges)\n - [Prototype Learnings](#prototype-learnings)\n - [Next Steps](#next-steps)\n - [Takeaways from ESE5160](#takeaways-from-ese5160)\n - [Project links](#project-links)\n- [3. Hardware \\\u0026 Software Requirements](#3-hardware--software-requirements)\n - [Hardware Requirements](#hardware-requirements)\n - [Software Requirements](#software-requirements)\n- [4. Project Photos \\\u0026 Screenshots](#4-project-photos--screenshots) --\u003e\n\n\n\u003ch2 class=\"relative group\"\u003e1. Project Photos \u0026amp; Screenshots \n \u003cdiv id=\"1-project-photos--screenshots\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#1-project-photos--screenshots\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eThe final project photo.\n\n \u003cfigure\u003e\n \u003cimg\n class=\"my-0 rounded-md\"\n loading=\"lazy\"\n srcset=\"\n /projects/embedded/pet_feeder/Pic/finalproject_hu_937e68ac6a594371.jpg 330w,\n /projects/embedded/pet_feeder/Pic/finalproject_hu_a3e222b22e286eac.jpg 660w,\n /projects/embedded/pet_feeder/Pic/finalproject_hu_254b13c7e51aa40a.jpg 1024w,\n /projects/embedded/pet_feeder/Pic/finalproject_hu_338f19bb7ab8e915.jpg 2x\"\n data-zoom-src=\"/projects/embedded/pet_feeder/Pic/finalproject_hu_338f19bb7ab8e915.jpg\"\n src=\"/projects/embedded/pet_feeder/Pic/finalproject_hu_a3e222b22e286eac.jpg\"\n alt=\"final\"\n /\u003e\n \n \u003c/figure\u003e\n\u003c/p\u003e","title":"A pet feeder","type":"projects"},{"content":" About Me # Hi, I\u0026rsquo;m S. Wang, a robotics enthusiast, embedded systems tinkerer, and lifelong learner with a passion for blending hardware and software into seamless solutions. Im currently a new graduate Masters student, and planning to work in ShenZhen, China.\nMy projects span a wide spectrum: from building quadrotor control systems and FPGA-based accelerators, to creating self-hosted tools. I love diving into low-level performance optimization, experimenting with control algorithms like PID, LQR, and MPC, and exploring AI integration for smarter automation.\nWhen Im not coding or soldering, youll find me behind a camera, capturing moments with the same attention to detail I bring to my engineering work. If youre into robotics, embedded systems, or self-hosted tech, well probably get along just fine.\nAbout This Site # Here is my personal corner of the internet - a space where I share my journey in robotics, embedded systems, control algorithms, and other technologies. Its more than just a blog — its my open lab notebook. I document everything from hardware design to software integration.\nEverything here is written with two goals in mind:\nTo help me think and learn better through documentation. To share ideas that might inspire or assist others working on similar challenges. ⚠️ Disclaimer: I cant promise everything here will be perfectly readable, but I do hope youll find something useful.\n","date":"20 September 2024","externalUrl":null,"permalink":"/about/","section":"About","summary":"\u003ch2 class=\"relative group\"\u003eAbout Me \n \u003cdiv id=\"about-me\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#about-me\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eHi, I\u0026rsquo;m S. Wang, a robotics enthusiast, embedded systems tinkerer, and lifelong learner with a passion for blending hardware and software into seamless solutions. Im currently a new graduate Masters student, and planning to work in ShenZhen, China.\u003c/p\u003e\n\u003cp\u003eMy projects span a wide spectrum: from building quadrotor control systems and FPGA-based accelerators, to creating self-hosted tools. I love diving into low-level performance optimization, experimenting with control algorithms like PID, LQR, and MPC, and exploring AI integration for smarter automation.\u003c/p\u003e","title":"About","type":"about"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/tags/ai/","section":"Tags","summary":"","title":"AI","type":"tags"},{"content":" Format Specifier # Common specifiers:\n%d int %u unsigned int %c char %s string (char s[]) %p void* %ld long %lld long long (64bits) %f float/double %lf float/double(usually used in scanf) We can extend the format specifiers:\nprintf(\u0026#34;%5d\u0026#34;, 33); // width \u0026#34; 33\u0026#34; printf(\u0026#34;%.2f\u0026#34;, 3.14159); // precision \u0026#34;3.14\u0026#34; printf(\u0026#34;%8.2f\u0026#34;, 3.14159);// \u0026#34; 3.14\u0026#34; printf(\u0026#34;%-5d\u0026#34;, 33); //Alignment \u0026#34;33 \u0026#34; IO # Read or print via terminal:\nint x; scanf(\u0026#34;%d\u0026#34;, \u0026amp;x); printf(\u0026#34;%d\u0026#34;, x); Type Conversion # String to int, float\u0026hellip;.\nint i = atoi(\u0026#34;123\u0026#34;); double d = atof(\u0026#34;3.14\u0026#34;); long l = strtol(\u0026#34;123\u0026#34;, NULL, 10); // safer, auto detec errors double d2 = strtod(\u0026#34;3.14\u0026#34;, NULL); Numbers to string:\nint i = 123; char buf[20]; sprintf(buf, \u0026#34;%d\u0026#34;, i); ","date":"20 September 2024","externalUrl":null,"permalink":"/notes/coding/cheat_sheet/c/","section":"Notes","summary":"\u003c!-- 笔试题有的时候不给正常输入只给plain text --\u003e\n\n\n\u003ch2 class=\"relative group\"\u003eFormat Specifier \n \u003cdiv id=\"format-specifier\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#format-specifier\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eCommon specifiers:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e%d int\n%u unsigned int\n%c char\n%s string (char s[])\n%p void*\n%ld long\n%lld long long (64bits)\n%f float/double\n%lf float/double(usually used in scanf)\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eWe can extend the format specifiers:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%5d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e33\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// width \u0026#34; 33\u0026#34; \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mf\"\u003e3.14159\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// precision \u0026#34;3.14\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%8.2f\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mf\"\u003e3.14159\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"c1\"\u003e// \u0026#34; 3.14\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%-5d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e33\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e//Alignment \u0026#34;33 \u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\n\u003ch2 class=\"relative group\"\u003eIO \n \u003cdiv id=\"io\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#io\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eRead or print via terminal:\u003c/p\u003e","title":"C","type":"notes"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/notes/coding/cheat_sheet/cpp/","section":"Notes","summary":"","title":"C++","type":"notes"},{"content":"Heres a cheat sheet of some programming languages, tools, and libraries that I use often—but somehow always forget.\n","date":"20 September 2024","externalUrl":null,"permalink":"/notes/coding/cheat_sheet/","section":"Notes","summary":"\u003cp\u003eHeres a cheat sheet of some programming languages, tools, and libraries that I use often—but somehow always forget.\u003c/p\u003e","title":"Cheat Sheets","type":"notes"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/series/cpu-architecture-notes/","section":"Series","summary":"","title":"CPU Architecture Notes","type":"series"},{"content":" Submodule # Commit # Add date and time in commit messages: git commit -m \u0026#34;$(date \u0026#39;+%Y-%m-%d %H:%M:%S\u0026#39;)\u0026#34; Remote # Check the remote url:\ngit remote -v If the remote url existing, set a new one:\ngit remote set-url origin \u0026lt;new_remote_address\u0026gt; A Trick: you can connect your local repo to 2 remote repos:\ngit remote add public https://\u0026lt;git_domain\u0026gt;/\u0026lt;username\u0026gt;/project-public.git git remote add private https://\u0026lt;git_domain\u0026gt;/\u0026lt;username\u0026gt;/project-private.git Branch # List all branches, the branch where you are currently working is marked with an asterisk (*):\ngit branch -a Move to a specific branch:\ngit checkout \u0026lt;branch_name\u0026gt; Create a new branch and switch to it:\ngit checkout -b \u0026lt;new_branch_name\u0026gt; Push # Let us break down the push command:\ngit push origin main , where origin is the remote name and main is the branch name. If you want to push to a different remote or branch, just replace them accordingly.\nMore advanced usage:\ngit push \u0026lt;remote_name\u0026gt; \u0026lt;local_branch_name\u0026gt;:\u0026lt;remote_branch_name\u0026gt; ","date":"20 September 2024","externalUrl":null,"permalink":"/notes/coding/cheat_sheet/git/","section":"Notes","summary":"\u003ch2 class=\"relative group\"\u003eSubmodule \n \u003cdiv id=\"submodule\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#submodule\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\n\n\u003ch2 class=\"relative group\"\u003eCommit \n \u003cdiv id=\"commit\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#commit\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eAdd date and time in commit messages:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit commit -m \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"k\"\u003e$(\u003c/span\u003edate \u003cspan class=\"s1\"\u003e\u0026#39;+%Y-%m-%d %H:%M:%S\u0026#39;\u003c/span\u003e\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\n\u003ch2 class=\"relative group\"\u003eRemote \n \u003cdiv id=\"remote\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#remote\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003eCheck the remote url:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit remote -v\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eIf the remote url existing, set a new one:\u003c/p\u003e","title":"Git","type":"notes"},{"content":" I am a recent graduate student.\nMy interests include robotics 🤖, embedded systems 📟, and photography 📸.\nHere, I will share my thoughts, notes, projects, and some interesting content. Stay tuned!\nSome Notes # Some Projects # ","date":"20 September 2024","externalUrl":null,"permalink":"/","section":"Home Page","summary":"\u003ch3 id=\"typeit-6fb22d3943ec7794c447a8e7c1bb77a4\"\u003e\u003c/h3\u003e\n\n\u003cscript\u003e\n document.addEventListener(\"DOMContentLoaded\", function () {\n new TypeIt(\"#typeit-6fb22d3943ec7794c447a8e7c1bb77a4\", {\n strings: [\"\",\"Welcome to my website! I'm really happy you stopped by.\",\"\"],\n speed: 100 ,\n lifeLike: true ,\n startDelay: 0 ,\n breakLines: true ,\n waitUntilVisible: true ,\n loop: false \n }).go();\n });\n\u003c/script\u003e\n\u003cp\u003eI am a recent graduate student.\u003c/p\u003e\n\u003cp\u003eMy interests include robotics 🤖, embedded systems 📟, and photography 📸.\u003c/p\u003e\n\u003cp\u003eHere, I will share my thoughts, notes, projects, and some interesting content. Stay tuned!\u003c/p\u003e\n\n\n\u003ch2 class=\"relative group\"\u003eSome Notes \n \u003cdiv id=\"some-notes\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#some-notes\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\n\n\u003ch2 class=\"relative group\"\u003eSome Projects \n \u003cdiv id=\"some-projects\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#some-projects\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e","title":"Home Page","type":"page"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/series/my-first-server-in-room/","section":"Series","summary":"","title":"My First Server in Room","type":"series"},{"content":"Personal notes, may not be readable.\n","date":"20 September 2024","externalUrl":null,"permalink":"/notes/","section":"Notes","summary":"\u003cp\u003ePersonal notes, may not be readable.\u003c/p\u003e","title":"Notes","type":"notes"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/tags/ongoing/","section":"Tags","summary":"","title":"Ongoing","type":"tags"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/tags/original/","section":"Tags","summary":"","title":"Original","type":"tags"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/zh-cn/tags/private/","section":"Tags","summary":"","title":"Private","type":"tags"},{"content":"This is the Projects page, where I keep track of all my personal and collaborative work.\nI use several tags to describe the status and nature of each project:\nPrivate/ Public: Private projects wont reveal too many details, but Ill still document the process, to-do lists, and partial results. For Public projects, I aim to share as much as possible — from design to implementation.\nIdea, Ongoing, Improving, Archived: These tags indicate the current state of a project — whether its just a thought, actively being developed, being refined, or no longer maintained.\nOriginal, Reproduce: Original means the project was initiated and designed by me. Reproduce refers to work based on existing ideas, papers, or open-source projects — typically with modifications or improvements.\n\u0026lt;Tags with other topic\u0026gt;: Some projects are interdisciplinary. Additional tags will be added to reflect relevant topics, but each project will be placed under the one category its most closely related to.\n","date":"20 September 2024","externalUrl":null,"permalink":"/projects/","section":"Projects","summary":"\u003cp\u003eThis is the Projects page, where I keep track of all my personal and collaborative work.\u003c/p\u003e\n\u003cp\u003eI use several tags to describe the status and nature of each project:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003ePrivate\u003c/code\u003e/ \u003ccode\u003ePublic\u003c/code\u003e: Private projects wont reveal too many details, but Ill still document the process, to-do lists, and partial results. For Public projects, I aim to share as much as possible — from design to implementation.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eIdea\u003c/code\u003e, \u003ccode\u003eOngoing\u003c/code\u003e, \u003ccode\u003eImproving\u003c/code\u003e, \u003ccode\u003eArchived\u003c/code\u003e: These tags indicate the current state of a project — whether its just a thought, actively being developed, being refined, or no longer maintained.\u003c/p\u003e","title":"Projects","type":"projects"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/tags/public/","section":"Tags","summary":"","title":"Public","type":"tags"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/notes/coding/cheat_sheet/python/","section":"Notes","summary":"","title":"Python","type":"notes"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/life/","section":"Rest Here","summary":"","title":"Rest Here","type":"life"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/series/stockbot/","section":"Series","summary":"","title":"StockBot","type":"series"},{"content":"","date":"20 September 2024","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":" Preview # 2025 graduation road trip, Las Vegas -\u0026gt; Grand Canyon -\u0026gt; Yellowstone -\u0026gt; Seattle -\u0026gt; CA-1 -\u0026gt; Las Vegas\n","date":"20 September 2024","externalUrl":null,"permalink":"/life/travel/","section":"Rest Here","summary":"\u003ch2 class=\"relative group\"\u003ePreview \n \u003cdiv id=\"preview\" class=\"anchor\"\u003e\u003c/div\u003e\n \n \u003cspan\n class=\"absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100\"\u003e\n \u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\"\n style=\"text-decoration-line: none !important;\" href=\"#preview\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n \u003c/span\u003e \n \n\u003c/h2\u003e\n\u003cp\u003e2025 graduation road trip, Las Vegas -\u0026gt; Grand Canyon -\u0026gt; Yellowstone -\u0026gt; Seattle -\u0026gt; CA-1 -\u0026gt; Las Vegas\u003c/p\u003e\n\n\n\u003cdiv id=\"gallery-e837f8dab5157d230a1317bf522b0c57\" class=\"gallery\"\u003e\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \u003cimg src=\"https://photo.swangnice.cn/api/assets/7609e40d-585b-4b6e-a7f2-dae2991f7a50/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=preview\u0026c=n%2FcVHYJ4eHePd3iGd3eIiGeAeQWp\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/4b1921f9-c1ea-4422-b7a8-c6f0044d7d45/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=preview\u0026c=jtYFLYZdd3fNiHiFeAeHcoRgTAi2\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/62292afd-bc31-4ade-bae0-de91539de284/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=thumbnail\u0026c=nfcJLYQtdlpbqmeHZ%2Fh4jIdwhAc2\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/b2622f51-5067-47f9-854a-40b606cdcfb7/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=thumbnail\u0026c=V9cNRYZoh3d%2FiHeKdzeHhXeAhQdX\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/26ad4345-65df-4fa0-abcd-177ede9b686d/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=thumbnail\u0026c=Z%2FcJHYJZiHeQeHhoiJeGd3iAkgc4\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/01d4cf9d-f0bd-4983-87ed-b14fbb4867c6/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=thumbnail\u0026c=GecJPYZniHeKeIiIeAeHh3iAdweI\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/3e486186-7717-40a0-9c94-25123d54da39/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=preview\u0026c=lOcFPQRnd393SIkYh3Oot3iAdgdY\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/414035f5-c42a-4a98-b5ce-63abc0546ffd/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=preview\u0026c=njgOFQZ6iJ%2BI53eHeGaIh3ZgYVcG\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/08d736c3-2e01-4d77-ae21-424385eaa3cb/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=preview\u0026c=ZgcKJYRniIiPZ4eEeGaGh3twywe3\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/c1307d7f-a167-40c2-ba3f-a93fbed8afa6/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=preview\u0026c=nhcOLQh4iI%2BIl4dIh4aIiHiAeAeI\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/f2699861-cd57-4da8-b7b8-4777507b5cc3/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=preview\u0026c=RwgGDYJHdqqRh4hwi6iGfFhwdpcI\" class=\"grid-w33\" /\u003e\n \u003cimg src=\"https://photo.swangnice.cn/api/assets/8163d339-eabb-4bcd-94bb-2ed5cb785092/thumbnail?key=PEvzdyJwfzxtIiW7pUt6y1qWiLGoLR_b0RVOJPIasJDLh4J6Bo6f8CCPQ1sJxkpPpA8\u0026size=preview\u0026c=2xcSJYRZh3iPhoeLiHeHeJhwpghl\" class=\"grid-w33\" /\u003e\n\n\u003c/div\u003e","title":"Travels","type":"life"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"}]