<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>勤骑车多拍照 on 夜云泊</title>
    <link>https://lifeislife.cn/categories/%E5%8B%A4%E9%AA%91%E8%BD%A6%E5%A4%9A%E6%8B%8D%E7%85%A7/</link>
    <description>feedId:57980998056508425+userId:73222296380546048 Recent content in 勤骑车多拍照 on 夜云泊</description>
    <generator>Hugo -- 0.157.0</generator>
    <language>zh</language>
    <lastBuildDate>Mon, 19 Jan 2026 10:34:10 +0000</lastBuildDate>
    <atom:link href="https://lifeislife.cn/categories/%E5%8B%A4%E9%AA%91%E8%BD%A6%E5%A4%9A%E6%8B%8D%E7%85%A7/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>半年动态血糖仪骑行实验</title>
      <link>https://lifeislife.cn/posts/%E5%8D%8A%E5%B9%B4%E5%8A%A8%E6%80%81%E8%A1%80%E7%B3%96%E4%BB%AA%E9%AA%91%E8%A1%8C%E5%AE%9E%E9%AA%8C/</link>
      <pubDate>Mon, 19 Jan 2026 10:34:10 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E5%8D%8A%E5%B9%B4%E5%8A%A8%E6%80%81%E8%A1%80%E7%B3%96%E4%BB%AA%E9%AA%91%E8%A1%8C%E5%AE%9E%E9%AA%8C/</guid>
      <description>&lt;h1 id=&#34;半年动态血糖仪骑行实验为什么我吃胶升不了糖了&#34;&gt;半年动态血糖仪骑行实验：为什么我吃胶“升不了糖”了？&lt;/h1&gt;
&lt;p&gt;我一直挺喜欢骑车。骑久了就绕不开一个现实问题：&lt;strong&gt;什么时候该补？补多少？补完有没有用？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;过去我都是凭感觉——饿了、腿软了、想吃甜的了就来一口。但越骑越久，我开始好奇：所谓“补能量”，到底是在干嘛？说白了很多时候就是在&lt;strong&gt;把血糖拉起来&lt;/strong&gt;。那问题来了：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我在骑行中，究竟什么时候真的需要“抬血糖”？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;半年前，我干了件有点“自虐式认真”的事：给自己买了一个动态血糖仪（CGM），准备把“凭感觉补给”变成“看数据补给”。&lt;/p&gt;
&lt;h2 id=&#34;最初的计划用血糖曲线给能量胶打分&#34;&gt;最初的计划：用血糖曲线给能量胶打分&lt;/h2&gt;
&lt;p&gt;CGM 最大的魅力是：你能直观看到“吃进去的碳水”对血糖造成的变化。于是我很自然地把好奇心转向了能量胶：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不同品牌的胶，升糖速度一样吗？&lt;/li&gt;
&lt;li&gt;峰值谁更高？&lt;/li&gt;
&lt;li&gt;谁能撑得更久？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我当时测了三个品牌：&lt;strong&gt;WIN、SIS、康比特&lt;/strong&gt;。结果很“教科书”：&lt;br&gt;
基本都是&lt;strong&gt;摄入后约 10 分钟开始上升&lt;/strong&gt;，随后出现明显抬升。&lt;/p&gt;
&lt;p&gt;为了让测试不至于变成“看个热闹”，我还给自己定了一个很朴素的评价标准：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;升糖幅度&lt;/strong&gt;（能不能把血糖拉起来）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;维持时间&lt;/strong&gt;（能不能撑住一段输出）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/143f99d255065710047372ede1eeda01.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/143f99d255065710047372ede1eeda01.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;那段时间我一度觉得：这事儿挺科学的，能做成一套属于自己的“骑行能量胶测评方法”。&lt;/p&gt;
&lt;p&gt;然后我被琐事打断了。测试停了，CGM 也就没再折腾。&lt;/p&gt;
&lt;h2 id=&#34;半年后重启我以为是继续更新数据结果直接翻车&#34;&gt;半年后重启：我以为是继续更新数据，结果直接翻车&lt;/h2&gt;
&lt;p&gt;最近我又想起这件事：市面上还有很多胶没测，我决定把这个坑补上。&lt;/p&gt;
&lt;p&gt;于是周六早上，我按之前的方式测了一个新品牌：&lt;strong&gt;Gio&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;结果让我当场愣住：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;几乎没有升糖反应&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;我等了将近 &lt;strong&gt;40 分钟&lt;/strong&gt; 才看到一点点波动&lt;/li&gt;
&lt;li&gt;血糖大概从 &lt;strong&gt;4.7 → 5.5 mmol/L&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;按我半年前的标准：&lt;strong&gt;不达标&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但这事儿离谱就在于：能量胶这么甜，怎么可能“没效果”？&lt;br&gt;
我不信邪，周六下午又测了一次——&lt;strong&gt;还是一样&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/563fe0871bacda69ab9806df3ff6e58d.jpg&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/563fe0871bacda69ab9806df3ff6e58d.jpg&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/d57574085f85728f13e053d0e70fae59.jpg&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/d57574085f85728f13e053d0e70fae59.jpg&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;这时候我的怀疑方向开始从“胶不行”变成“我是不是出问题了”。更要命的是，周六我状态确实不太好，下午整个人有点迷糊，越想越像身体不对劲。&lt;/p&gt;
&lt;h2 id=&#34;复测老朋友-win我状态很好但血糖依旧毫无波澜&#34;&gt;复测老朋友 WIN：我状态很好，但血糖依旧毫无波澜&lt;/h2&gt;
&lt;p&gt;周日早上醒来，我状态很好，精神也清爽。我决定做一个最直接的排查：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;用半年前测过、当时表现“很正常”的 WIN 再测一次。&lt;br&gt;
看看是我身体变了，还是胶变了，还是方法变了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;结果：&lt;strong&gt;WIN 也不升了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/1e6a5d9b075a73a436b0730e445767db.jpg&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/1e6a5d9b075a73a436b0730e445767db.jpg&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/aca38638a8923eca00cfc5546dfdbf8d.jpg&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/aca38638a8923eca00cfc5546dfdbf8d.jpg&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;后面明显血糖提升是我已经停止骑行了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;那种感觉很微妙：&lt;br&gt;
不是“数据不好看”的失落，而是“我一直以为这个方法靠谱，现在它好像失效了”的错愕。&lt;/p&gt;
&lt;p&gt;我当时的心理活动大概是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果 Gio 不升糖，可能是胶的问题&lt;/li&gt;
&lt;li&gt;但 WIN 也不升，那就很难怪胶&lt;/li&gt;
&lt;li&gt;我今天状态又很好，不像身体出毛病&lt;/li&gt;
&lt;li&gt;那到底发生了什么？&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;把曲线丢给-chatgpt一个我之前没认真想过的可能&#34;&gt;把曲线丢给 ChatGPT：一个我之前没认真想过的可能&lt;/h2&gt;
&lt;p&gt;我把半年前和最近的曲线发给 ChatGPT 让它帮我分析。它给了一个核心判断，听起来反直觉但很合理：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;不是你吸收变差了，而是你“用得更快了”。&lt;/strong&gt;&lt;br&gt;
糖进来了，但还没来得及在血液里堆高，就被肌肉直接拿去用掉了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;它解释的方向主要是这些（我用自己的话压缩一下）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;训练适应后，肌肉即时摄糖能力变强&lt;/strong&gt;：同样一包胶，过去会“血糖冲高”，现在可能直接被消耗掉&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运动状态下肌肉收缩也能吸糖&lt;/strong&gt;（不完全靠胰岛素那条路），骑得越规律这条路越“顺手”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CGM 测到的是“血液/组织液里剩多少”&lt;/strong&gt;，不等于“你吃进去了多少”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句话总结就是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;半年前是“摄入 &amp;gt; 消耗”，所以曲线抬头明显；&lt;br&gt;
现在更像“摄入 ≈ 消耗”，所以曲线看起来风平浪静。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当时我看到这套解释，第一反应不是“懂了”，而是“那我怎么确认不是瞎猜？”&lt;/p&gt;
&lt;h2 id=&#34;我做了一个关键对照静坐吃胶血糖立刻起飞&#34;&gt;我做了一个关键对照：静坐吃胶，血糖立刻起飞&lt;/h2&gt;
&lt;p&gt;周一上班，我干脆做了个更粗暴但有效的对照实验：&lt;br&gt;
&lt;strong&gt;不骑车、不运动、静坐状态下吃一根 Gio。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;结果非常清晰：&lt;strong&gt;血糖在短时间内迅速上升。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/32187d7b86e8debc5134516798cfce3f.jpg&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/32187d7b86e8debc5134516798cfce3f.jpg&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;这一下基本把几个疑点都排掉了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;胶没问题（至少碳水摄入是实打实的）&lt;/li&gt;
&lt;li&gt;我的吸收没问题&lt;/li&gt;
&lt;li&gt;CGM 也没坏&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那剩下的解释就更集中：&lt;strong&gt;运动状态改变了“血糖呈现方式”&lt;/strong&gt;。不是没吃进去，而是“进来就被用掉”，所以你在曲线上看不到当年那种抬升。&lt;/p&gt;
&lt;h2 id=&#34;我真正的收获我那套测评标准其实脆弱得很&#34;&gt;我真正的收获：我那套“测评标准”，其实脆弱得很&lt;/h2&gt;
&lt;p&gt;这次翻车让我重新认识了一件事：&lt;strong&gt;人体的变量多到离谱&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我半年前以为自己设计了一个挺科学的测评框架：看升糖幅度、看维持时间，然后给能量胶打分。现在回头看，这个框架至少有一个致命前提：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你的身体状态得相对稳定，你得能控制足够多的变量。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但现实是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同一个人，不同训练周期、不同疲劳程度、不同睡眠、不同压力&lt;/li&gt;
&lt;li&gt;同一种胶，可能会呈现完全不同的血糖曲线&lt;/li&gt;
&lt;li&gt;甚至同一个周末，上午和下午都能不一样&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以也就不难理解：为什么大厂很少做这种“用血糖曲线评测能量胶效果”的公开对比。不是他们不想，是因为这事儿&lt;strong&gt;太难控制变量&lt;/strong&gt;，结论很容易被误读。&lt;/p&gt;
&lt;h2 id=&#34;接下来我准备怎么继续这个坑我还想挖&#34;&gt;接下来我准备怎么继续（这个坑我还想挖）&lt;/h2&gt;
&lt;p&gt;这次之后，我不太想把“能量胶评测”继续做成那种“谁升糖猛谁赢”的榜单了。更有意思的方向可能是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;运动 vs 静息&lt;/strong&gt; 同一支胶的差异（像这次一样）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不同强度区间（Z2、爬坡、间歇）&lt;/strong&gt; 同样摄入的曲线变化&lt;/li&gt;
&lt;li&gt;把“血糖是否抬头”从结论，降级为一个观察维度&lt;/li&gt;
&lt;li&gt;更关注：&lt;strong&gt;骑行主观感受、功率输出、胃部舒适度&lt;/strong&gt;与血糖的对应关系&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我现在越来越觉得：CGM 更像一面镜子，它照出来的不只是“胶怎么样”，更多是“我现在的身体处在什么状态”。&lt;/p&gt;
&lt;h2 id=&#34;结尾我以为我在测胶结果是在测自己&#34;&gt;结尾：我以为我在测胶，结果是在测自己&lt;/h2&gt;
&lt;p&gt;这次最让我佩服的不是某个品牌的胶，也不是某条漂亮曲线，而是人体这套系统的精密程度：&lt;/p&gt;
&lt;p&gt;我以为“吃胶＝升血糖”，结果运动状态下它可能变成“吃胶＝直接被肌肉拿走用掉”。&lt;br&gt;
我以为我的方法很科学，结果它只是在一个特定阶段刚好有效。&lt;/p&gt;
&lt;p&gt;这大概就是我喜欢做这种长期小实验的原因：&lt;br&gt;
骑行没有标准答案，但数据会逼你承认——你还远远没弄懂自己。&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h1 id="半年动态血糖仪骑行实验为什么我吃胶升不了糖了">半年动态血糖仪骑行实验：为什么我吃胶“升不了糖”了？</h1>
<p>我一直挺喜欢骑车。骑久了就绕不开一个现实问题：<strong>什么时候该补？补多少？补完有没有用？</strong></p>
<p>过去我都是凭感觉——饿了、腿软了、想吃甜的了就来一口。但越骑越久，我开始好奇：所谓“补能量”，到底是在干嘛？说白了很多时候就是在<strong>把血糖拉起来</strong>。那问题来了：</p>
<blockquote>
<p>我在骑行中，究竟什么时候真的需要“抬血糖”？</p>
</blockquote>
<p>半年前，我干了件有点“自虐式认真”的事：给自己买了一个动态血糖仪（CGM），准备把“凭感觉补给”变成“看数据补给”。</p>
<h2 id="最初的计划用血糖曲线给能量胶打分">最初的计划：用血糖曲线给能量胶打分</h2>
<p>CGM 最大的魅力是：你能直观看到“吃进去的碳水”对血糖造成的变化。于是我很自然地把好奇心转向了能量胶：</p>
<ul>
<li>不同品牌的胶，升糖速度一样吗？</li>
<li>峰值谁更高？</li>
<li>谁能撑得更久？</li>
</ul>
<p>我当时测了三个品牌：<strong>WIN、SIS、康比特</strong>。结果很“教科书”：<br>
基本都是<strong>摄入后约 10 分钟开始上升</strong>，随后出现明显抬升。</p>
<p>为了让测试不至于变成“看个热闹”，我还给自己定了一个很朴素的评价标准：</p>
<ul>
<li><strong>升糖幅度</strong>（能不能把血糖拉起来）</li>
<li><strong>维持时间</strong>（能不能撑住一段输出）</li>
</ul>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/143f99d255065710047372ede1eeda01.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/143f99d255065710047372ede1eeda01.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>那段时间我一度觉得：这事儿挺科学的，能做成一套属于自己的“骑行能量胶测评方法”。</p>
<p>然后我被琐事打断了。测试停了，CGM 也就没再折腾。</p>
<h2 id="半年后重启我以为是继续更新数据结果直接翻车">半年后重启：我以为是继续更新数据，结果直接翻车</h2>
<p>最近我又想起这件事：市面上还有很多胶没测，我决定把这个坑补上。</p>
<p>于是周六早上，我按之前的方式测了一个新品牌：<strong>Gio</strong>。</p>
<p>结果让我当场愣住：</p>
<ul>
<li><strong>几乎没有升糖反应</strong></li>
<li>我等了将近 <strong>40 分钟</strong> 才看到一点点波动</li>
<li>血糖大概从 <strong>4.7 → 5.5 mmol/L</strong></li>
<li>按我半年前的标准：<strong>不达标</strong></li>
</ul>
<p>但这事儿离谱就在于：能量胶这么甜，怎么可能“没效果”？<br>
我不信邪，周六下午又测了一次——<strong>还是一样</strong>。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/563fe0871bacda69ab9806df3ff6e58d.jpg">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/563fe0871bacda69ab9806df3ff6e58d.jpg" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/d57574085f85728f13e053d0e70fae59.jpg">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/d57574085f85728f13e053d0e70fae59.jpg" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>这时候我的怀疑方向开始从“胶不行”变成“我是不是出问题了”。更要命的是，周六我状态确实不太好，下午整个人有点迷糊，越想越像身体不对劲。</p>
<h2 id="复测老朋友-win我状态很好但血糖依旧毫无波澜">复测老朋友 WIN：我状态很好，但血糖依旧毫无波澜</h2>
<p>周日早上醒来，我状态很好，精神也清爽。我决定做一个最直接的排查：</p>
<blockquote>
<p>用半年前测过、当时表现“很正常”的 WIN 再测一次。<br>
看看是我身体变了，还是胶变了，还是方法变了。</p>
</blockquote>
<p>结果：<strong>WIN 也不升了。</strong></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/1e6a5d9b075a73a436b0730e445767db.jpg">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/1e6a5d9b075a73a436b0730e445767db.jpg" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/aca38638a8923eca00cfc5546dfdbf8d.jpg">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/aca38638a8923eca00cfc5546dfdbf8d.jpg" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<blockquote>
<p>后面明显血糖提升是我已经停止骑行了</p>
</blockquote>
<p>那种感觉很微妙：<br>
不是“数据不好看”的失落，而是“我一直以为这个方法靠谱，现在它好像失效了”的错愕。</p>
<p>我当时的心理活动大概是：</p>
<ul>
<li>如果 Gio 不升糖，可能是胶的问题</li>
<li>但 WIN 也不升，那就很难怪胶</li>
<li>我今天状态又很好，不像身体出毛病</li>
<li>那到底发生了什么？</li>
</ul>
<h2 id="把曲线丢给-chatgpt一个我之前没认真想过的可能">把曲线丢给 ChatGPT：一个我之前没认真想过的可能</h2>
<p>我把半年前和最近的曲线发给 ChatGPT 让它帮我分析。它给了一个核心判断，听起来反直觉但很合理：</p>
<blockquote>
<p><strong>不是你吸收变差了，而是你“用得更快了”。</strong><br>
糖进来了，但还没来得及在血液里堆高，就被肌肉直接拿去用掉了。</p>
</blockquote>
<p>它解释的方向主要是这些（我用自己的话压缩一下）：</p>
<ul>
<li><strong>训练适应后，肌肉即时摄糖能力变强</strong>：同样一包胶，过去会“血糖冲高”，现在可能直接被消耗掉</li>
<li><strong>运动状态下肌肉收缩也能吸糖</strong>（不完全靠胰岛素那条路），骑得越规律这条路越“顺手”</li>
<li><strong>CGM 测到的是“血液/组织液里剩多少”</strong>，不等于“你吃进去了多少”</li>
</ul>
<p>一句话总结就是：</p>
<blockquote>
<p>半年前是“摄入 &gt; 消耗”，所以曲线抬头明显；<br>
现在更像“摄入 ≈ 消耗”，所以曲线看起来风平浪静。</p>
</blockquote>
<p>当时我看到这套解释，第一反应不是“懂了”，而是“那我怎么确认不是瞎猜？”</p>
<h2 id="我做了一个关键对照静坐吃胶血糖立刻起飞">我做了一个关键对照：静坐吃胶，血糖立刻起飞</h2>
<p>周一上班，我干脆做了个更粗暴但有效的对照实验：<br>
<strong>不骑车、不运动、静坐状态下吃一根 Gio。</strong></p>
<p>结果非常清晰：<strong>血糖在短时间内迅速上升。</strong></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/32187d7b86e8debc5134516798cfce3f.jpg">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2026/01/20/32187d7b86e8debc5134516798cfce3f.jpg" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>这一下基本把几个疑点都排掉了：</p>
<ul>
<li>胶没问题（至少碳水摄入是实打实的）</li>
<li>我的吸收没问题</li>
<li>CGM 也没坏</li>
</ul>
<p>那剩下的解释就更集中：<strong>运动状态改变了“血糖呈现方式”</strong>。不是没吃进去，而是“进来就被用掉”，所以你在曲线上看不到当年那种抬升。</p>
<h2 id="我真正的收获我那套测评标准其实脆弱得很">我真正的收获：我那套“测评标准”，其实脆弱得很</h2>
<p>这次翻车让我重新认识了一件事：<strong>人体的变量多到离谱</strong>。</p>
<p>我半年前以为自己设计了一个挺科学的测评框架：看升糖幅度、看维持时间，然后给能量胶打分。现在回头看，这个框架至少有一个致命前提：</p>
<blockquote>
<p>你的身体状态得相对稳定，你得能控制足够多的变量。</p>
</blockquote>
<p>但现实是：</p>
<ul>
<li>同一个人，不同训练周期、不同疲劳程度、不同睡眠、不同压力</li>
<li>同一种胶，可能会呈现完全不同的血糖曲线</li>
<li>甚至同一个周末，上午和下午都能不一样</li>
</ul>
<p>所以也就不难理解：为什么大厂很少做这种“用血糖曲线评测能量胶效果”的公开对比。不是他们不想，是因为这事儿<strong>太难控制变量</strong>，结论很容易被误读。</p>
<h2 id="接下来我准备怎么继续这个坑我还想挖">接下来我准备怎么继续（这个坑我还想挖）</h2>
<p>这次之后，我不太想把“能量胶评测”继续做成那种“谁升糖猛谁赢”的榜单了。更有意思的方向可能是：</p>
<ul>
<li><strong>运动 vs 静息</strong> 同一支胶的差异（像这次一样）</li>
<li><strong>不同强度区间（Z2、爬坡、间歇）</strong> 同样摄入的曲线变化</li>
<li>把“血糖是否抬头”从结论，降级为一个观察维度</li>
<li>更关注：<strong>骑行主观感受、功率输出、胃部舒适度</strong>与血糖的对应关系</li>
</ul>
<p>我现在越来越觉得：CGM 更像一面镜子，它照出来的不只是“胶怎么样”，更多是“我现在的身体处在什么状态”。</p>
<h2 id="结尾我以为我在测胶结果是在测自己">结尾：我以为我在测胶，结果是在测自己</h2>
<p>这次最让我佩服的不是某个品牌的胶，也不是某条漂亮曲线，而是人体这套系统的精密程度：</p>
<p>我以为“吃胶＝升血糖”，结果运动状态下它可能变成“吃胶＝直接被肌肉拿走用掉”。<br>
我以为我的方法很科学，结果它只是在一个特定阶段刚好有效。</p>
<p>这大概就是我喜欢做这种长期小实验的原因：<br>
骑行没有标准答案，但数据会逼你承认——你还远远没弄懂自己。</p>
]]></content:encoded>
    </item>
    <item>
      <title>Zwift单机版多人联机教程</title>
      <link>https://lifeislife.cn/posts/zwift%E5%8D%95%E6%9C%BA%E7%89%88%E5%A4%9A%E4%BA%BA%E8%81%94%E6%9C%BA%E6%95%99%E7%A8%8B/</link>
      <pubDate>Mon, 18 Aug 2025 10:03:10 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/zwift%E5%8D%95%E6%9C%BA%E7%89%88%E5%A4%9A%E4%BA%BA%E8%81%94%E6%9C%BA%E6%95%99%E7%A8%8B/</guid>
      <description>&lt;p&gt;创建普通用户，用户名为user&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;useradd -m user
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;修改默认shell为bash&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo usermod -s /bin/bash user
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;添加用户到sudoers&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo usermod -aG sudo user
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;立即生效配置&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo newgrp sudo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;修改用户密码&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo passwd user
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一键安装Docker&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://cdn.jsdelivr.net/gh/muzihuaner/docker-install@master/install.sh -o install-docker.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sh install-docker.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;配置镜像仓库&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;registry-mirrors&amp;#34;: [&amp;#34;https://docker.1ms.run&amp;#34;]}&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sudo tee /etc/docker/daemon.json &amp;gt; /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        systemctl restart docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;添加当前用户到docker组，避免每次使用docker命令时都需要sudo&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo usermod -aG docker &lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;生效配置&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;newgrp docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;常见问题&#34;&gt;常见问题&lt;/h1&gt;
&lt;h2 id=&#34;安卓客户端登录密码错误-password-invalid&#34;&gt;安卓客户端登录密码错误 password invalid&lt;/h2&gt;
&lt;p&gt;确保hosts中的域名都能够被正常解析。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;127.0.0.1 us-or-rly101.zwift.com 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;127.0.0.1 secure.zwift.com 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;127.0.0.1 cdn.zwift.com 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安卓设备可以下载应用&lt;code&gt;Termux&lt;/code&gt;，可以使用&lt;code&gt;ping&lt;/code&gt;命令检查域名是否能够被正常解析。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ping us-or-rly101.zwift.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ping secure.zwift.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ping cdn.zwift.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一定到注意每个域名都测试一遍，之前有遇到过只有部分域名能够被正常解析的情况。如果发现部分域名能够被正常解析，而部分域名不能被正常解析，可以尝试使用txt编辑工具，比如&lt;code&gt;txtpad&lt;/code&gt;，不要使用WPS，Microsoft Word等工具来编辑，这些工具可能会自动将域名转换为其他格式，导致无法被正常解析。用&lt;code&gt;txtpad&lt;/code&gt;编辑后，保存为&lt;code&gt;hosts.txt&lt;/code&gt;文件到能找到的位置，然后重新使用&lt;code&gt;ping&lt;/code&gt;命令检查域名是否能够被正常解析。&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<p>创建普通用户，用户名为user</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">useradd -m user
</span></span></code></pre></div><p>修改默认shell为bash</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo usermod -s /bin/bash user
</span></span></code></pre></div><p>添加用户到sudoers</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo usermod -aG sudo user
</span></span></code></pre></div><p>立即生效配置</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo newgrp sudo
</span></span></code></pre></div><p>修改用户密码</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo passwd user
</span></span></code></pre></div><p>一键安装Docker</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -fsSL https://cdn.jsdelivr.net/gh/muzihuaner/docker-install@master/install.sh -o install-docker.sh
</span></span><span class="line"><span class="cl">sh install-docker.sh
</span></span></code></pre></div><p>配置镜像仓库</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s1">&#39;{&#34;registry-mirrors&#34;: [&#34;https://docker.1ms.run&#34;]}&#39;</span> <span class="p">|</span> sudo tee /etc/docker/daemon.json &gt; /dev/null
</span></span><span class="line"><span class="cl">        systemctl daemon-reload
</span></span><span class="line"><span class="cl">        systemctl restart docker
</span></span></code></pre></div><p>添加当前用户到docker组，避免每次使用docker命令时都需要sudo</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo usermod -aG docker <span class="nv">$USER</span>
</span></span></code></pre></div><p>生效配置</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">newgrp docker
</span></span></code></pre></div><h1 id="常见问题">常见问题</h1>
<h2 id="安卓客户端登录密码错误-password-invalid">安卓客户端登录密码错误 password invalid</h2>
<p>确保hosts中的域名都能够被正常解析。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">127.0.0.1 us-or-rly101.zwift.com 
</span></span><span class="line"><span class="cl">127.0.0.1 secure.zwift.com 
</span></span><span class="line"><span class="cl">127.0.0.1 cdn.zwift.com 
</span></span></code></pre></div><p>安卓设备可以下载应用<code>Termux</code>，可以使用<code>ping</code>命令检查域名是否能够被正常解析。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ping us-or-rly101.zwift.com
</span></span><span class="line"><span class="cl">ping secure.zwift.com
</span></span><span class="line"><span class="cl">ping cdn.zwift.com
</span></span></code></pre></div><p>一定到注意每个域名都测试一遍，之前有遇到过只有部分域名能够被正常解析的情况。如果发现部分域名能够被正常解析，而部分域名不能被正常解析，可以尝试使用txt编辑工具，比如<code>txtpad</code>，不要使用WPS，Microsoft Word等工具来编辑，这些工具可能会自动将域名转换为其他格式，导致无法被正常解析。用<code>txtpad</code>编辑后，保存为<code>hosts.txt</code>文件到能找到的位置，然后重新使用<code>ping</code>命令检查域名是否能够被正常解析。</p>
]]></content:encoded>
    </item>
    <item>
      <title>探险家V900 GPS轨迹记录器折腾笔记</title>
      <link>https://lifeislife.cn/posts/%E6%8E%A2%E9%99%A9%E5%AE%B6v900-gps%E8%BD%A8%E8%BF%B9%E8%AE%B0%E5%BD%95%E5%99%A8%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Tue, 01 Jul 2025 14:10:20 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E6%8E%A2%E9%99%A9%E5%AE%B6v900-gps%E8%BD%A8%E8%BF%B9%E8%AE%B0%E5%BD%95%E5%99%A8%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;h1 id=&#34;一切要从一个软件开始&#34;&gt;一切要从一个软件开始&lt;/h1&gt;
&lt;p&gt;某天看到Strava上自己的骑行轨迹，仓鼠的天性开始显露，既然能记录骑行的轨迹，为啥不把开车轨迹，步行轨迹都记录了？虽然早就听说了世界迷雾（Fog of World），但是因为走过的地方并不多，再加上安装过程比较复杂，所以一直没有尝试。现在看到骑行的地方越来越多，世界迷雾（Fog of World）的诱惑越来越大，于是开始折腾。&lt;/p&gt;
&lt;p&gt;使用这个软件就不多说了，反正倒腾Google Pay就捣鼓了好久，又花了20刀乐买了这个软件。&lt;/p&gt;
&lt;p&gt;虽然这个软件本身就是自带轨迹记录功能，但是使用手机导航的都知道，任何需要GPS功能的软件都是耗电大户，让这个软件常驻后台显然不能接受，一次偶然的机会，看到了这个设备，原来可以通过外置GPS记录轨迹，于是开始折腾。&lt;/p&gt;
&lt;h1 id=&#34;探险家v900-gps轨迹记录器&#34;&gt;探险家V900 GPS轨迹记录器&lt;/h1&gt;
&lt;p&gt;一个快20年前的产品，早已经停产，目前只能找到它的升级版V990以及性能更好的产品，但是价格也贵了不少。即使现在能找到在售的V990，价格也要500块，还是没有舍得。只能在闲鱼上淘一下，140块淘了一个品相还不错的V900。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/7dc5957f8418b66ee4c0ff0fe2826123.jpg&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/7dc5957f8418b66ee4c0ff0fe2826123.jpg&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/c0f7e0fadddd6d6899c4ac5f062905fa.jpg&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/c0f7e0fadddd6d6899c4ac5f062905fa.jpg&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/e487c85699bae5fec64f5a42c3156f39.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/e487c85699bae5fec64f5a42c3156f39.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/1d9e0ba43c6e52466da0d5b0fcd470e9.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/1d9e0ba43c6e52466da0d5b0fcd470e9.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;因为对GPS硬件一窍不通，也不知道这个规格里的性能如何，只是想当然觉得专用的GPS记录器应该至少比手机强吧，但是东西到手只能感叹一句，技术进步太快了。&lt;/p&gt;
&lt;p&gt;这玩意只能获取GPS信号，但是现在最廉价的手机都能支持多种定位方式，包括GPS，北斗，GLONASS等等信号了，这意味它获取定位的精度和速度都远远不如手机。&lt;/p&gt;
&lt;p&gt;在室内定位了很久都没有定位成功，又专门到楼下空地还是无法定位，最终只能放弃，退回卖家，但是卖家也可能觉得是老古董了，估计很难卖出去，最终答应20块钱卖给我。我心想20块钱买个曾经500块的玩具，也挺划算的，于是就收下了。既然能开机，说明硬件应该没问题，应该还是能用的。&lt;/p&gt;
&lt;h1 id=&#34;折腾过程&#34;&gt;折腾过程&lt;/h1&gt;
&lt;h2 id=&#34;无法定位&#34;&gt;无法定位&lt;/h2&gt;
&lt;p&gt;因为设备很久没有开机定位了，所以相当于冷启动，通常获取GPS信号时间就会很久，之前买新的码表时就会遇到这种情况，第一次定位花了很久，以为设备坏了，后来定位成功一次后，后续定位就很快了。于是我又找了一块广场空地开始定位，这次果然定位成功了。&lt;/p&gt;
&lt;p&gt;所以想要解决定位问题，首先不能在室内，室内因为混凝土遮挡信号，几乎无法定位成功，第一次定位时最好找个没有遮挡的空地，3-5分钟基本上能定位成功。&lt;/p&gt;
&lt;h2 id=&#34;无法记录轨迹&#34;&gt;无法记录轨迹&lt;/h2&gt;
&lt;p&gt;这个问题包括插入内存卡后，开机后自动关机，定位成功后设备发出急促的哔哔哔声音，这些都是因为内存卡分区格式问题导致的。&lt;/p&gt;
&lt;p&gt;因为这是快20年前的产品，那时候的内存卡大多还是4G以下的内存，文件系统还是FAT格式，现在想要买一个4G以下的内存卡都很难了，所以能见到的大部分内存卡都是无法直接在这个设备上使用，必须格式化成FAT格式。所以最好找一个小容量的卡，如果是4G以下的卡，通常可以在电脑上直接格式化为FAT或者FAT16，如果大于4G的卡，那就需要专门的软件来格式化了，并且格式化之后的容量最大就只有4G，所以最好买一个小容量卡。&lt;/p&gt;
&lt;p&gt;格式化的工具和步骤可以参考这个链接：&lt;a href=&#34;https://www.cbgps.com/download/format/index_en.html&#34;&gt;How to record tracks in V-990/V-900 with a MicroSD card (Capacity above 4G)&lt;/a&gt;。虽然是老古董产品，但是这个常见的售后支持做的还是很到位的，这么多年都还保留了所有产品的文档和相关工具。&lt;/p&gt;
&lt;p&gt;最终卡信息如下：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/27314625d6dc6026c5401508ebdf119f.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/27314625d6dc6026c5401508ebdf119f.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/705b229d7c2da473502de4d412969437.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/705b229d7c2da473502de4d412969437.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;产品文档链接：&lt;a href=&#34;https://www.cbgps.com/download.htm&#34;&gt;支持和下载&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/17e88c53a9bf685312a4fc4b26beafa5.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/17e88c53a9bf685312a4fc4b26beafa5.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;使用蓝牙连接设备&#34;&gt;使用蓝牙连接设备&lt;/h2&gt;
&lt;p&gt;这个功能当初开发出来应该是为了给一些软件提供第三方的导航功能的，但是现在导航工具已经触手可得，这个功能就没什么用了。如果你想尝试一下这个功能，可以下载一个Bluetooth GPS软件，&lt;a href=&#34;https://bluetooth-gps.cn.uptodown.com/android&#34;&gt;Bluetooth GPS针对于Android - 从Uptodown上下载APK&lt;/a&gt;来连接设备。&lt;/p&gt;
&lt;p&gt;链接过程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;长按开机键开机，自动进入蓝牙模式，蓝牙灯闪烁&lt;/li&gt;
&lt;li&gt;打开手机蓝牙，搜索设备，找到设备后点击连接，设备名称为Columbus GPS&lt;/li&gt;
&lt;li&gt;输入匹配码0000连接设备&lt;/li&gt;
&lt;li&gt;打开软件选择Columbus GPS，点击连接&lt;/li&gt;
&lt;li&gt;连接成功后，软件会显示设备信息，包括经纬度，速度，海拔等&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/35fe63a86d0c09df17996669003f41bb.jpg&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/35fe63a86d0c09df17996669003f41bb.jpg&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h1 id=&#34;轨迹实测&#34;&gt;轨迹实测&lt;/h1&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/72d0441f8c4f8a5ebc776699af1ec85e.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/72d0441f8c4f8a5ebc776699af1ec85e.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;蓝色是佳明Forerunner 255的运动轨迹，红色是V900的轨迹，可以看到V900的性能在今天来说完全不够看了，漂移严重，并且海拔信息几乎不可用，这么点距离海拔爬升200多，在海宁这种大平原上，走一天都爬不了这么高。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/8d16c4a47497dd12b62a63842b7c764d.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/8d16c4a47497dd12b62a63842b7c764d.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h1 id="一切要从一个软件开始">一切要从一个软件开始</h1>
<p>某天看到Strava上自己的骑行轨迹，仓鼠的天性开始显露，既然能记录骑行的轨迹，为啥不把开车轨迹，步行轨迹都记录了？虽然早就听说了世界迷雾（Fog of World），但是因为走过的地方并不多，再加上安装过程比较复杂，所以一直没有尝试。现在看到骑行的地方越来越多，世界迷雾（Fog of World）的诱惑越来越大，于是开始折腾。</p>
<p>使用这个软件就不多说了，反正倒腾Google Pay就捣鼓了好久，又花了20刀乐买了这个软件。</p>
<p>虽然这个软件本身就是自带轨迹记录功能，但是使用手机导航的都知道，任何需要GPS功能的软件都是耗电大户，让这个软件常驻后台显然不能接受，一次偶然的机会，看到了这个设备，原来可以通过外置GPS记录轨迹，于是开始折腾。</p>
<h1 id="探险家v900-gps轨迹记录器">探险家V900 GPS轨迹记录器</h1>
<p>一个快20年前的产品，早已经停产，目前只能找到它的升级版V990以及性能更好的产品，但是价格也贵了不少。即使现在能找到在售的V990，价格也要500块，还是没有舍得。只能在闲鱼上淘一下，140块淘了一个品相还不错的V900。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/7dc5957f8418b66ee4c0ff0fe2826123.jpg">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/7dc5957f8418b66ee4c0ff0fe2826123.jpg" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/c0f7e0fadddd6d6899c4ac5f062905fa.jpg">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/c0f7e0fadddd6d6899c4ac5f062905fa.jpg" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/e487c85699bae5fec64f5a42c3156f39.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/e487c85699bae5fec64f5a42c3156f39.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/1d9e0ba43c6e52466da0d5b0fcd470e9.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/1d9e0ba43c6e52466da0d5b0fcd470e9.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>因为对GPS硬件一窍不通，也不知道这个规格里的性能如何，只是想当然觉得专用的GPS记录器应该至少比手机强吧，但是东西到手只能感叹一句，技术进步太快了。</p>
<p>这玩意只能获取GPS信号，但是现在最廉价的手机都能支持多种定位方式，包括GPS，北斗，GLONASS等等信号了，这意味它获取定位的精度和速度都远远不如手机。</p>
<p>在室内定位了很久都没有定位成功，又专门到楼下空地还是无法定位，最终只能放弃，退回卖家，但是卖家也可能觉得是老古董了，估计很难卖出去，最终答应20块钱卖给我。我心想20块钱买个曾经500块的玩具，也挺划算的，于是就收下了。既然能开机，说明硬件应该没问题，应该还是能用的。</p>
<h1 id="折腾过程">折腾过程</h1>
<h2 id="无法定位">无法定位</h2>
<p>因为设备很久没有开机定位了，所以相当于冷启动，通常获取GPS信号时间就会很久，之前买新的码表时就会遇到这种情况，第一次定位花了很久，以为设备坏了，后来定位成功一次后，后续定位就很快了。于是我又找了一块广场空地开始定位，这次果然定位成功了。</p>
<p>所以想要解决定位问题，首先不能在室内，室内因为混凝土遮挡信号，几乎无法定位成功，第一次定位时最好找个没有遮挡的空地，3-5分钟基本上能定位成功。</p>
<h2 id="无法记录轨迹">无法记录轨迹</h2>
<p>这个问题包括插入内存卡后，开机后自动关机，定位成功后设备发出急促的哔哔哔声音，这些都是因为内存卡分区格式问题导致的。</p>
<p>因为这是快20年前的产品，那时候的内存卡大多还是4G以下的内存，文件系统还是FAT格式，现在想要买一个4G以下的内存卡都很难了，所以能见到的大部分内存卡都是无法直接在这个设备上使用，必须格式化成FAT格式。所以最好找一个小容量的卡，如果是4G以下的卡，通常可以在电脑上直接格式化为FAT或者FAT16，如果大于4G的卡，那就需要专门的软件来格式化了，并且格式化之后的容量最大就只有4G，所以最好买一个小容量卡。</p>
<p>格式化的工具和步骤可以参考这个链接：<a href="https://www.cbgps.com/download/format/index_en.html">How to record tracks in V-990/V-900 with a MicroSD card (Capacity above 4G)</a>。虽然是老古董产品，但是这个常见的售后支持做的还是很到位的，这么多年都还保留了所有产品的文档和相关工具。</p>
<p>最终卡信息如下：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/27314625d6dc6026c5401508ebdf119f.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/27314625d6dc6026c5401508ebdf119f.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/705b229d7c2da473502de4d412969437.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/705b229d7c2da473502de4d412969437.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>产品文档链接：<a href="https://www.cbgps.com/download.htm">支持和下载</a></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/17e88c53a9bf685312a4fc4b26beafa5.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/17e88c53a9bf685312a4fc4b26beafa5.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="使用蓝牙连接设备">使用蓝牙连接设备</h2>
<p>这个功能当初开发出来应该是为了给一些软件提供第三方的导航功能的，但是现在导航工具已经触手可得，这个功能就没什么用了。如果你想尝试一下这个功能，可以下载一个Bluetooth GPS软件，<a href="https://bluetooth-gps.cn.uptodown.com/android">Bluetooth GPS针对于Android - 从Uptodown上下载APK</a>来连接设备。</p>
<p>链接过程如下：</p>
<ol>
<li>长按开机键开机，自动进入蓝牙模式，蓝牙灯闪烁</li>
<li>打开手机蓝牙，搜索设备，找到设备后点击连接，设备名称为Columbus GPS</li>
<li>输入匹配码0000连接设备</li>
<li>打开软件选择Columbus GPS，点击连接</li>
<li>连接成功后，软件会显示设备信息，包括经纬度，速度，海拔等</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/35fe63a86d0c09df17996669003f41bb.jpg">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/35fe63a86d0c09df17996669003f41bb.jpg" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h1 id="轨迹实测">轨迹实测</h1>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/72d0441f8c4f8a5ebc776699af1ec85e.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/72d0441f8c4f8a5ebc776699af1ec85e.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>蓝色是佳明Forerunner 255的运动轨迹，红色是V900的轨迹，可以看到V900的性能在今天来说完全不够看了，漂移严重，并且海拔信息几乎不可用，这么点距离海拔爬升200多，在海宁这种大平原上，走一天都爬不了这么高。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/8d16c4a47497dd12b62a63842b7c764d.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/07/03/8d16c4a47497dd12b62a63842b7c764d.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
]]></content:encoded>
    </item>
    <item>
      <title>Docker Compose 部署 Strava Statistics</title>
      <link>https://lifeislife.cn/posts/docker-compose%E9%83%A8%E7%BD%B2strava-statistics/</link>
      <pubDate>Sat, 08 Mar 2025 10:34:10 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/docker-compose%E9%83%A8%E7%BD%B2strava-statistics/</guid>
      <description>&lt;h1 id=&#34;strava-statistics-部署文档&#34;&gt;Strava Statistics 部署文档&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/robiningelbrecht/strava-statistics&#34;&gt;Strava Statistics&lt;/a&gt; 是一个自托管工具，利用 Strava 数据生成个人运动统计，支持 Docker 部署，提供丰富的可视化分析。下面介绍如何使用 Docker Compose 部署。&lt;/p&gt;
&lt;h2 id=&#34;申请-strava-的-api-权限&#34;&gt;申请 Strava 的 API 权限&lt;/h2&gt;
&lt;p&gt;在&lt;a href=&#34;https://lifeislife.cn/awesome-cycling/docs/training-fitness/zwiftoffline/&#34;&gt;ZwiftOffline&lt;/a&gt;中也需要用到 API 权限，因为不同应用程序也不冲突，懒得再重新申请，所以以下填的信息使用的 ZwiftOffline 的 API 权限。&lt;/p&gt;
&lt;p&gt;登录&lt;a href=&#34;https://www.strava.com/settings/api&#34;&gt;Strava&lt;/a&gt;，申请 API，获取&lt;code&gt;Client ID&lt;/code&gt;和&lt;code&gt;Client Secret&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;填写内容可以参考下图：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/d8024be9518e5a262538aa5d48c7fbb0.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/d8024be9518e5a262538aa5d48c7fbb0.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;其中授权回调域填写：launcher.zwift.com&lt;/p&gt;
&lt;p&gt;申请完成后会得到下面的信息：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/a5024f9e2e150810251222315be11ac9.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/a5024f9e2e150810251222315be11ac9.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;将下面链接中的&lt;code&gt;client_id&lt;/code&gt;值换成上图中的客户 ID，然后浏览器中访问这个链接：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://www.strava.com/oauth/authorize?client_id=xxxxxxx&amp;amp;response_type=code&amp;amp;redirect_uri=http://localhost/exchange_token&amp;amp;approval_prompt=force&amp;amp;scope=activity:read_all
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;点击授权：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/89a9c1d81d40e6b4687531ab92d689a2.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/89a9c1d81d40e6b4687531ab92d689a2.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;此时跳转到一个无法访问的网页，将地址栏中的&lt;code&gt;code&lt;/code&gt;值记录下来，后面需要用到：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/c3a74e83d363bb0f453ad37712dd28ac.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/c3a74e83d363bb0f453ad37712dd28ac.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;需要用这个&lt;code&gt;code&lt;/code&gt;发起一个 cURL 请求得到&lt;code&gt;refresh_token&lt;/code&gt;，具体做法是在命令行终端中执行下面的命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	curl -X POST https://www.strava.com/oauth/token &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	-F &lt;span class=&#34;nv&#34;&gt;client_id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;YOURCLIENTID &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	-F &lt;span class=&#34;nv&#34;&gt;client_secret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;YOURCLIENTSECRET &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	-F &lt;span class=&#34;nv&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;AUTHORIZATIONCODE &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	-F &lt;span class=&#34;nv&#34;&gt;grant_type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;authorization_code
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;client_id&lt;/code&gt;值替换为申请得到的&lt;code&gt;客户ID&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;client_secret&lt;/code&gt;值替换为申请得到的&lt;code&gt;客户端密钥&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;code&lt;/code&gt;替换为上一步浏览器中得到的&lt;code&gt;code&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;执行成功后可以得到下面的返回信息，需要将返回值中的&lt;code&gt;refresh_token&lt;/code&gt;和&lt;code&gt;access_token&lt;/code&gt;记录下来，后面需要用到：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;token_type&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;Bearer&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;expires_at&amp;#34;&lt;/span&gt;:1740213400,&lt;span class=&#34;s2&#34;&gt;&amp;#34;expires_in&amp;#34;&lt;/span&gt;:21600,&lt;span class=&#34;s2&#34;&gt;&amp;#34;refresh_token&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;123456789123456789&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;access_token&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;123456789123456789&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;athlete&amp;#34;&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:117756825,&lt;span class=&#34;s2&#34;&gt;&amp;#34;username&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;dunky_zhang&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;resource_state&amp;#34;&lt;/span&gt;:2,&lt;span class=&#34;s2&#34;&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;Dominic&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;lastname&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;Zhang&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;bio&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;骑行小白&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;city&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;country&amp;#34;&lt;/span&gt;:null,&lt;span class=&#34;s2&#34;&gt;&amp;#34;sex&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;M&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;premium&amp;#34;&lt;/span&gt;:true,&lt;span class=&#34;s2&#34;&gt;&amp;#34;summit&amp;#34;&lt;/span&gt;:true,&lt;span class=&#34;s2&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;2023-05-10T13:54:32Z&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-02-06T05:29:52Z&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;badge_type_id&amp;#34;&lt;/span&gt;:1,&lt;span class=&#34;s2&#34;&gt;&amp;#34;weight&amp;#34;&lt;/span&gt;:66.0,&lt;span class=&#34;s2&#34;&gt;&amp;#34;profile_medium&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://dgalywyr863hv.cloudfront.net/pictures/athletes/117756825/32138099/2/medium.jpg&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;profile&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://dgalywyr863hv.cloudfront.net/pictures/athletes/117756825/32138099/2/large.jpg&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;friend&amp;#34;&lt;/span&gt;:null,&lt;span class=&#34;s2&#34;&gt;&amp;#34;follower&amp;#34;&lt;/span&gt;:null&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;docker-compose-部署-strava-statistics&#34;&gt;Docker Compose 部署 Strava Statistics&lt;/h2&gt;
&lt;p&gt;创建目录用于存放 Strava Statistics 的配置文件&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mkdir statistics-for-strava
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; statistics-for-strava
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;创建 &lt;code&gt;docker-compose.yml&lt;/code&gt; 文件&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;touch docker-compose.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;编辑 &lt;code&gt;docker-compose.yml&lt;/code&gt; 文件，填入以下内容：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;robiningelbrecht/strava-statistics:latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;./build:/var/www/build&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;./storage/database:/var/www/storage/database&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;./storage/files:/var/www/storage/files&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;./.env&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;PUID=1000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;PGID=1000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;TZ=Asia/Shanghai&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 因为 Strava 的 API 需要代理访问，所以下面设置了我的代理地址，请你根据自己的代理地址进行设置&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;http_proxy=http://192.168.1.9:7890&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;https_proxy=http://192.168.1.9:7890&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;all_proxy=socks5://192.168.1.9:7891&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;创建 &lt;code&gt;.env&lt;/code&gt; 文件&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;touch .env
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;编辑 &lt;code&gt;.env&lt;/code&gt; 文件，填入以下内容：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 应用程序将托管的URL。此URL将用于清单文件中。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 这将允许您将Web应用程序作为原生应用程序安装到您的设备上。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;MANIFEST_APP_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://localhost:8080/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 您的Strava应用程序的客户端ID。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;STRAVA_CLIENT_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;xxxxxxx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 您的Strava应用程序的客户端密钥。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;STRAVA_CLIENT_SECRET&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;xxxxxxxxxxxxxx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 您的Strava应用程序的刷新令牌。在上一步获取到的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;STRAVA_REFRESH_TOKEN&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;xxxxxxxxxxxxxx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Strava API有限速限制（https://github.com/robiningelbrecht/strava-statistics/wiki），&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 为了确保我们不会达到限速，我们希望限制每次导入处理的新活动数量。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 考虑到每天有1000次请求限制，并且导入一个新活动最多可能需要3次API调用，250应该是一个安全的数字。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;NUMBER_OF_NEW_ACTIVITIES_TO_PROCESS_PER_IMPORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;250&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 定期运行导入和HTML构建的计划。留空以禁用定期导入。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 默认计划为每天凌晨04:05运行一次。如果您不知道什么是cron表达式，请勿更改此项。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 请确保不要过于频繁地运行导入，以避免达到Strava API的限速。每天一次应该足够。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;IMPORT_AND_BUILD_SCHEDULE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;5 4 * * *&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 设置用于计划的时区&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 有效的时区可以在此处找到（TZ标识符列）：https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;TZ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;Asia/Shanghai
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 允许的选项：en_US、fr_FR 或 nl_BE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;LOCALE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;en_US
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 允许的选项：metric（公制）或 imperial（英制）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;UNIT_SYSTEM&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;metric
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 渲染应用程序时使用的时间格式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 允许的格式：24 或 12（包括AM和PM）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;TIME_FORMAT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 渲染应用程序时使用的日期格式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 允许的格式：DAY-MONTH-YEAR（日-月-年）或 MONTH-DAY-YEAR（月-日-年）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DATE_FORMAT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;DAY-MONTH-YEAR
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 要导入的运动类型。留空以导入所有运动类型。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 通过此列表，您还可以决定运动类型的渲染顺序。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 完整的允许选项列表可在以下地址找到：https://github.com/robiningelbrecht/strava-statistics/wiki/Supported-sport-types/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;SPORT_TYPES_TO_IMPORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;[]&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 您的生日。需要用于计算心率区间。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ATHLETE_BIRTHDAY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1999-01-01
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 体重历史（单位为千克或磅，取决于UNIT_SYSTEM）。需要用于计算相对功率重量比（w/kg）。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 查看更多信息：https://github.com/robiningelbrecht/strava-statistics/wiki&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ATHLETE_WEIGHTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;1970-01-01&amp;#34;: 68
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# FTP（功能阈值功率）历史。需要用于计算活动压力水平。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 查看更多信息：https://github.com/robiningelbrecht/strava-statistics/wiki&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;FTP_VALUES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;2024-12-12&amp;#34;: 235
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 包含ntfy主题的完整URL。此主题将用于在新的HTML构建运行时通知您。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 留空以禁用通知。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;NTFY_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 在导入期间要跳过的活动ID数组。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 这允许您在导入时跳过特定活动。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ACTIVITIES_TO_SKIP_DURING_IMPORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;[]&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 创建/拥有由strava-statistics管理的文件的UID和GID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 可能仅在Linux主机上需要，详见Wiki中的文件权限部分&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#PUID=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#PGID=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;开始导入数据：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;启动容器&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker-compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;导入数据&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; App bin/console app:strava:import-data
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; App bin/console app:strava:build-files
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;导入过程非常非常慢，因为需要挨个数据获取，并且很容易出错，如果出错了，需要先关闭容器，然后重新导入。以下是导入成功的截图：


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/af3c468483a1c46544c02b5c2d8124ac.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/af3c468483a1c46544c02b5c2d8124ac.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;访问 &lt;code&gt;localhost:8080&lt;/code&gt; 查看数据&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/07a1a21d1c53ab4560de20f5cbcb60db.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/07a1a21d1c53ab4560de20f5cbcb60db.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;常见问题&#34;&gt;常见问题&lt;/h2&gt;
&lt;h3 id=&#34;401-unauthorized&#34;&gt;401 Unauthorized&lt;/h3&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/22/a541f82e213a98de7f9e69a614e0e7bc.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/22/a541f82e213a98de7f9e69a614e0e7bc.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.env&lt;/code&gt;中的&lt;code&gt;STRAVA_REFRESH_TOKEN&lt;/code&gt;可能过期，需要重新获取。又或者压根就忘记了获取&lt;code&gt;refresh_token&lt;/code&gt;，需要重新获取。&lt;/p&gt;
&lt;h3 id=&#34;failed-to-connect-to-nominatimopenstreetmaporg&#34;&gt;Failed to connect to nominatim.openstreetmap.org&lt;/h3&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/22/86b6394d0eca978d164927d9129641ea.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/22/86b6394d0eca978d164927d9129641ea.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;因为需要生成一些地图热点信息，所以需要访问 nominatim.openstreetmap.org，所以需要配置代理。&lt;/p&gt;
&lt;h3 id=&#34;tring-to-calculate-the-relative-power-for-activity&#34;&gt;Tring to calculate the relative power for activity&lt;/h3&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/e39d6ef29c3288646bfd500908e58e0c.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/e39d6ef29c3288646bfd500908e58e0c.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;因为需要计算相对功率重量比（w/kg），所以需要配置体重历史。如果发现某个活动的时间点没有配置体重信息就会报这个错。看看&lt;code&gt;.env&lt;/code&gt;中的&lt;code&gt;ATHLETE_WEIGHTS&lt;/code&gt;是否配置正确。我建议直接修改成我提供的数据，也就是从 1970 年开始都是当前的体重。因为我尝试配置了自己的体重历史，但是一直报错，所以直接改成了这个。&lt;/p&gt;
&lt;h3 id=&#34;looks-like-you-still-need-to-import-your-strava-data&#34;&gt;Looks like you still need to import your strava data&lt;/h3&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/e31949d1bf03a1df838b21a74908bfbc.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/e31949d1bf03a1df838b21a74908bfbc.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;如果你只执行了&lt;code&gt;docker-compose up -d&lt;/code&gt;，而没有执行导入数据的命令，那么就会出现这个错误。需要执行导入数据的命令。如果你已经导入成功了，如果还报这个错，就需要重启一下容器。&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h1 id="strava-statistics-部署文档">Strava Statistics 部署文档</h1>
<p><a href="https://github.com/robiningelbrecht/strava-statistics">Strava Statistics</a> 是一个自托管工具，利用 Strava 数据生成个人运动统计，支持 Docker 部署，提供丰富的可视化分析。下面介绍如何使用 Docker Compose 部署。</p>
<h2 id="申请-strava-的-api-权限">申请 Strava 的 API 权限</h2>
<p>在<a href="https://lifeislife.cn/awesome-cycling/docs/training-fitness/zwiftoffline/">ZwiftOffline</a>中也需要用到 API 权限，因为不同应用程序也不冲突，懒得再重新申请，所以以下填的信息使用的 ZwiftOffline 的 API 权限。</p>
<p>登录<a href="https://www.strava.com/settings/api">Strava</a>，申请 API，获取<code>Client ID</code>和<code>Client Secret</code>。</p>
<p>填写内容可以参考下图：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/d8024be9518e5a262538aa5d48c7fbb0.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/d8024be9518e5a262538aa5d48c7fbb0.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>其中授权回调域填写：launcher.zwift.com</p>
<p>申请完成后会得到下面的信息：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/a5024f9e2e150810251222315be11ac9.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/a5024f9e2e150810251222315be11ac9.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>将下面链接中的<code>client_id</code>值换成上图中的客户 ID，然后浏览器中访问这个链接：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">http://www.strava.com/oauth/authorize?client_id=xxxxxxx&amp;response_type=code&amp;redirect_uri=http://localhost/exchange_token&amp;approval_prompt=force&amp;scope=activity:read_all
</span></span></code></pre></div><p>点击授权：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/89a9c1d81d40e6b4687531ab92d689a2.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/89a9c1d81d40e6b4687531ab92d689a2.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>此时跳转到一个无法访问的网页，将地址栏中的<code>code</code>值记录下来，后面需要用到：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/c3a74e83d363bb0f453ad37712dd28ac.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/c3a74e83d363bb0f453ad37712dd28ac.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>需要用这个<code>code</code>发起一个 cURL 请求得到<code>refresh_token</code>，具体做法是在命令行终端中执行下面的命令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">	curl -X POST https://www.strava.com/oauth/token <span class="se">\
</span></span></span><span class="line"><span class="cl">	-F <span class="nv">client_id</span><span class="o">=</span>YOURCLIENTID <span class="se">\
</span></span></span><span class="line"><span class="cl">	-F <span class="nv">client_secret</span><span class="o">=</span>YOURCLIENTSECRET <span class="se">\
</span></span></span><span class="line"><span class="cl">	-F <span class="nv">code</span><span class="o">=</span>AUTHORIZATIONCODE <span class="se">\
</span></span></span><span class="line"><span class="cl">	-F <span class="nv">grant_type</span><span class="o">=</span>authorization_code
</span></span></code></pre></div><ul>
<li><code>client_id</code>值替换为申请得到的<code>客户ID</code></li>
<li><code>client_secret</code>值替换为申请得到的<code>客户端密钥</code></li>
<li><code>code</code>替换为上一步浏览器中得到的<code>code</code></li>
</ul>
<p>执行成功后可以得到下面的返回信息，需要将返回值中的<code>refresh_token</code>和<code>access_token</code>记录下来，后面需要用到：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="o">{</span><span class="s2">&#34;token_type&#34;</span>:<span class="s2">&#34;Bearer&#34;</span>,<span class="s2">&#34;expires_at&#34;</span>:1740213400,<span class="s2">&#34;expires_in&#34;</span>:21600,<span class="s2">&#34;refresh_token&#34;</span>:<span class="s2">&#34;123456789123456789&#34;</span>,<span class="s2">&#34;access_token&#34;</span>:<span class="s2">&#34;123456789123456789&#34;</span>,<span class="s2">&#34;athlete&#34;</span>:<span class="o">{</span><span class="s2">&#34;id&#34;</span>:117756825,<span class="s2">&#34;username&#34;</span>:<span class="s2">&#34;dunky_zhang&#34;</span>,<span class="s2">&#34;resource_state&#34;</span>:2,<span class="s2">&#34;firstname&#34;</span>:<span class="s2">&#34;Dominic&#34;</span>,<span class="s2">&#34;lastname&#34;</span>:<span class="s2">&#34;Zhang&#34;</span>,<span class="s2">&#34;bio&#34;</span>:<span class="s2">&#34;骑行小白&#34;</span>,<span class="s2">&#34;city&#34;</span>:<span class="s2">&#34;&#34;</span>,<span class="s2">&#34;state&#34;</span>:<span class="s2">&#34;&#34;</span>,<span class="s2">&#34;country&#34;</span>:null,<span class="s2">&#34;sex&#34;</span>:<span class="s2">&#34;M&#34;</span>,<span class="s2">&#34;premium&#34;</span>:true,<span class="s2">&#34;summit&#34;</span>:true,<span class="s2">&#34;created_at&#34;</span>:<span class="s2">&#34;2023-05-10T13:54:32Z&#34;</span>,<span class="s2">&#34;updated_at&#34;</span>:<span class="s2">&#34;2025-02-06T05:29:52Z&#34;</span>,<span class="s2">&#34;badge_type_id&#34;</span>:1,<span class="s2">&#34;weight&#34;</span>:66.0,<span class="s2">&#34;profile_medium&#34;</span>:<span class="s2">&#34;https://dgalywyr863hv.cloudfront.net/pictures/athletes/117756825/32138099/2/medium.jpg&#34;</span>,<span class="s2">&#34;profile&#34;</span>:<span class="s2">&#34;https://dgalywyr863hv.cloudfront.net/pictures/athletes/117756825/32138099/2/large.jpg&#34;</span>,<span class="s2">&#34;friend&#34;</span>:null,<span class="s2">&#34;follower&#34;</span>:null<span class="o">}}</span><span class="c1">#</span>
</span></span></code></pre></div><h2 id="docker-compose-部署-strava-statistics">Docker Compose 部署 Strava Statistics</h2>
<p>创建目录用于存放 Strava Statistics 的配置文件</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir statistics-for-strava
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> statistics-for-strava
</span></span></code></pre></div><p>创建 <code>docker-compose.yml</code> 文件</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">touch docker-compose.yml
</span></span></code></pre></div><p>编辑 <code>docker-compose.yml</code> 文件，填入以下内容：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">app</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">robiningelbrecht/strava-statistics:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./build:/var/www/build</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./storage/database:/var/www/storage/database</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./storage/files:/var/www/storage/files</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">env_file</span><span class="p">:</span><span class="w"> </span><span class="l">./.env</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="m">8080</span><span class="p">:</span><span class="m">8080</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">PUID=1000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">PGID=1000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">TZ=Asia/Shanghai</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 因为 Strava 的 API 需要代理访问，所以下面设置了我的代理地址，请你根据自己的代理地址进行设置</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">http_proxy=http://192.168.1.9:7890</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">https_proxy=http://192.168.1.9:7890</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">all_proxy=socks5://192.168.1.9:7891</span><span class="w">
</span></span></span></code></pre></div><p>创建 <code>.env</code> 文件</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">touch .env
</span></span></code></pre></div><p>编辑 <code>.env</code> 文件，填入以下内容：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 应用程序将托管的URL。此URL将用于清单文件中。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 这将允许您将Web应用程序作为原生应用程序安装到您的设备上。</span>
</span></span><span class="line"><span class="cl"><span class="nv">MANIFEST_APP_URL</span><span class="o">=</span>http://localhost:8080/
</span></span><span class="line"><span class="cl"><span class="c1"># 您的Strava应用程序的客户端ID。</span>
</span></span><span class="line"><span class="cl"><span class="nv">STRAVA_CLIENT_ID</span><span class="o">=</span>xxxxxxx
</span></span><span class="line"><span class="cl"><span class="c1"># 您的Strava应用程序的客户端密钥。</span>
</span></span><span class="line"><span class="cl"><span class="nv">STRAVA_CLIENT_SECRET</span><span class="o">=</span>xxxxxxxxxxxxxx
</span></span><span class="line"><span class="cl"><span class="c1"># 您的Strava应用程序的刷新令牌。在上一步获取到的</span>
</span></span><span class="line"><span class="cl"><span class="nv">STRAVA_REFRESH_TOKEN</span><span class="o">=</span>xxxxxxxxxxxxxx
</span></span><span class="line"><span class="cl"><span class="c1"># Strava API有限速限制（https://github.com/robiningelbrecht/strava-statistics/wiki），</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 为了确保我们不会达到限速，我们希望限制每次导入处理的新活动数量。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 考虑到每天有1000次请求限制，并且导入一个新活动最多可能需要3次API调用，250应该是一个安全的数字。</span>
</span></span><span class="line"><span class="cl"><span class="nv">NUMBER_OF_NEW_ACTIVITIES_TO_PROCESS_PER_IMPORT</span><span class="o">=</span><span class="m">250</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 定期运行导入和HTML构建的计划。留空以禁用定期导入。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 默认计划为每天凌晨04:05运行一次。如果您不知道什么是cron表达式，请勿更改此项。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 请确保不要过于频繁地运行导入，以避免达到Strava API的限速。每天一次应该足够。</span>
</span></span><span class="line"><span class="cl"><span class="nv">IMPORT_AND_BUILD_SCHEDULE</span><span class="o">=</span><span class="s2">&#34;5 4 * * *&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 设置用于计划的时区</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 有效的时区可以在此处找到（TZ标识符列）：https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List</span>
</span></span><span class="line"><span class="cl"><span class="nv">TZ</span><span class="o">=</span>Asia/Shanghai
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 允许的选项：en_US、fr_FR 或 nl_BE</span>
</span></span><span class="line"><span class="cl"><span class="nv">LOCALE</span><span class="o">=</span>en_US
</span></span><span class="line"><span class="cl"><span class="c1"># 允许的选项：metric（公制）或 imperial（英制）</span>
</span></span><span class="line"><span class="cl"><span class="nv">UNIT_SYSTEM</span><span class="o">=</span>metric
</span></span><span class="line"><span class="cl"><span class="c1"># 渲染应用程序时使用的时间格式</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 允许的格式：24 或 12（包括AM和PM）</span>
</span></span><span class="line"><span class="cl"><span class="nv">TIME_FORMAT</span><span class="o">=</span><span class="m">24</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 渲染应用程序时使用的日期格式</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 允许的格式：DAY-MONTH-YEAR（日-月-年）或 MONTH-DAY-YEAR（月-日-年）</span>
</span></span><span class="line"><span class="cl"><span class="nv">DATE_FORMAT</span><span class="o">=</span>DAY-MONTH-YEAR
</span></span><span class="line"><span class="cl"><span class="c1"># 要导入的运动类型。留空以导入所有运动类型。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 通过此列表，您还可以决定运动类型的渲染顺序。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 完整的允许选项列表可在以下地址找到：https://github.com/robiningelbrecht/strava-statistics/wiki/Supported-sport-types/</span>
</span></span><span class="line"><span class="cl"><span class="nv">SPORT_TYPES_TO_IMPORT</span><span class="o">=</span><span class="s1">&#39;[]&#39;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 您的生日。需要用于计算心率区间。</span>
</span></span><span class="line"><span class="cl"><span class="nv">ATHLETE_BIRTHDAY</span><span class="o">=</span>1999-01-01
</span></span><span class="line"><span class="cl"><span class="c1"># 体重历史（单位为千克或磅，取决于UNIT_SYSTEM）。需要用于计算相对功率重量比（w/kg）。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 查看更多信息：https://github.com/robiningelbrecht/strava-statistics/wiki</span>
</span></span><span class="line"><span class="cl"><span class="nv">ATHLETE_WEIGHTS</span><span class="o">=</span><span class="s1">&#39;{
</span></span></span><span class="line"><span class="cl"><span class="s1">    &#34;1970-01-01&#34;: 68
</span></span></span><span class="line"><span class="cl"><span class="s1">}&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># FTP（功能阈值功率）历史。需要用于计算活动压力水平。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 查看更多信息：https://github.com/robiningelbrecht/strava-statistics/wiki</span>
</span></span><span class="line"><span class="cl"><span class="nv">FTP_VALUES</span><span class="o">=</span><span class="s1">&#39;{
</span></span></span><span class="line"><span class="cl"><span class="s1">    &#34;2024-12-12&#34;: 235
</span></span></span><span class="line"><span class="cl"><span class="s1">}&#39;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 包含ntfy主题的完整URL。此主题将用于在新的HTML构建运行时通知您。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 留空以禁用通知。</span>
</span></span><span class="line"><span class="cl"><span class="nv">NTFY_URL</span><span class="o">=</span><span class="s1">&#39;&#39;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 在导入期间要跳过的活动ID数组。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 这允许您在导入时跳过特定活动。</span>
</span></span><span class="line"><span class="cl"><span class="nv">ACTIVITIES_TO_SKIP_DURING_IMPORT</span><span class="o">=</span><span class="s1">&#39;[]&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 创建/拥有由strava-statistics管理的文件的UID和GID</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 可能仅在Linux主机上需要，详见Wiki中的文件权限部分</span>
</span></span><span class="line"><span class="cl"><span class="c1">#PUID=</span>
</span></span><span class="line"><span class="cl"><span class="c1">#PGID=</span>
</span></span></code></pre></div><p>开始导入数据：</p>
<ul>
<li>
<p>启动容器</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker-compose up -d
</span></span></code></pre></div></li>
<li>
<p>导入数据</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose <span class="nb">exec</span> App bin/console app:strava:import-data
</span></span><span class="line"><span class="cl">docker compose <span class="nb">exec</span> App bin/console app:strava:build-files
</span></span></code></pre></div><p>导入过程非常非常慢，因为需要挨个数据获取，并且很容易出错，如果出错了，需要先关闭容器，然后重新导入。以下是导入成功的截图：


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/af3c468483a1c46544c02b5c2d8124ac.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/af3c468483a1c46544c02b5c2d8124ac.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
</li>
<li>
<p>访问 <code>localhost:8080</code> 查看数据</p>
</li>
</ul>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/07a1a21d1c53ab4560de20f5cbcb60db.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/03/08/07a1a21d1c53ab4560de20f5cbcb60db.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="常见问题">常见问题</h2>
<h3 id="401-unauthorized">401 Unauthorized</h3>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/22/a541f82e213a98de7f9e69a614e0e7bc.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/22/a541f82e213a98de7f9e69a614e0e7bc.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p><code>.env</code>中的<code>STRAVA_REFRESH_TOKEN</code>可能过期，需要重新获取。又或者压根就忘记了获取<code>refresh_token</code>，需要重新获取。</p>
<h3 id="failed-to-connect-to-nominatimopenstreetmaporg">Failed to connect to nominatim.openstreetmap.org</h3>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/22/86b6394d0eca978d164927d9129641ea.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/22/86b6394d0eca978d164927d9129641ea.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>因为需要生成一些地图热点信息，所以需要访问 nominatim.openstreetmap.org，所以需要配置代理。</p>
<h3 id="tring-to-calculate-the-relative-power-for-activity">Tring to calculate the relative power for activity</h3>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/e39d6ef29c3288646bfd500908e58e0c.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/e39d6ef29c3288646bfd500908e58e0c.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>因为需要计算相对功率重量比（w/kg），所以需要配置体重历史。如果发现某个活动的时间点没有配置体重信息就会报这个错。看看<code>.env</code>中的<code>ATHLETE_WEIGHTS</code>是否配置正确。我建议直接修改成我提供的数据，也就是从 1970 年开始都是当前的体重。因为我尝试配置了自己的体重历史，但是一直报错，所以直接改成了这个。</p>
<h3 id="looks-like-you-still-need-to-import-your-strava-data">Looks like you still need to import your strava data</h3>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/e31949d1bf03a1df838b21a74908bfbc.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/23/e31949d1bf03a1df838b21a74908bfbc.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>如果你只执行了<code>docker-compose up -d</code>，而没有执行导入数据的命令，那么就会出现这个错误。需要执行导入数据的命令。如果你已经导入成功了，如果还报这个错，就需要重启一下容器。</p>
]]></content:encoded>
    </item>
    <item>
      <title>Zwift 单机版安装教程</title>
      <link>https://lifeislife.cn/posts/zwift%E5%8D%95%E6%9C%BA%E7%89%88%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/</link>
      <pubDate>Sun, 09 Feb 2025 10:34:10 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/zwift%E5%8D%95%E6%9C%BA%E7%89%88%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/</guid>
      <description>&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/zoffline/zwift-offline?tab=readme-ov-file&#34;&gt;ZwiftOffline&lt;/a&gt;是一个开源社区自制的 Zwift 的 server 端，可以在没有网络的情况下进行 Zwift 课程或路线训练，多平台支持。&lt;/p&gt;
&lt;p&gt;本教程将详细介绍如何在 Windows 系统上安装和配置 Zwift 单机版，包括基础安装、账号配置、Strava 同步、训练课程上传以及移动端 Companion 配置等完整流程。&lt;/p&gt;
&lt;h2 id=&#34;一准备工作&#34;&gt;一、准备工作&lt;/h2&gt;
&lt;h3 id=&#34;11-下载必要文件&#34;&gt;1.1 下载必要文件&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ZwiftOffline 主程序&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从&lt;a href=&#34;https://github.com/zoffline/zwift-offline/releases/latest&#34;&gt;GitHub Release 页面&lt;/a&gt;下载最新的 zoffline 发布版（&lt;code&gt;.exe&lt;/code&gt;文件）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配置辅助工具&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从&lt;a href=&#34;https://github.com/oldnapalm/zoffline-helper/releases/latest&#34;&gt;GitHub Release&lt;/a&gt;下载&lt;code&gt;zoffline-helper.zip&lt;/code&gt;配置脚本文件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Zwift 官方客户端&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前往&lt;a href=&#34;https://www.zwift.com/&#34;&gt;Zwift 官网&lt;/a&gt;，拉到页面底部，下载并安装 Zwift 软件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重要&lt;/strong&gt;：记住安装路径，后续配置需要用到（例如：&lt;code&gt;C:\Program Files (x86)\Zwift&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;12-创建运行目录&#34;&gt;1.2 创建运行目录&lt;/h3&gt;
&lt;p&gt;创建一个目录用于存放 ZwiftOffline 相关文件，例如新建&lt;code&gt;zwiftoffline&lt;/code&gt;目录。&lt;/p&gt;
&lt;h2 id=&#34;二基础安装与配置&#34;&gt;二、基础安装与配置&lt;/h2&gt;
&lt;h3 id=&#34;21-初始化-zwiftoffline&#34;&gt;2.1 初始化 ZwiftOffline&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;将下载的&lt;code&gt;zoffline.exe&lt;/code&gt;文件保存到&lt;code&gt;zwiftoffline&lt;/code&gt;目录&lt;/li&gt;
&lt;li&gt;运行&lt;code&gt;zoffline.exe&lt;/code&gt;，程序会在同目录下自动创建&lt;code&gt;storage&lt;/code&gt;目录（用于保存 Zwift 进度）&lt;/li&gt;
&lt;li&gt;看到&lt;code&gt;storage&lt;/code&gt;目录生成后，按&lt;code&gt;Ctrl+C&lt;/code&gt;关闭 zoffline，稍后进行配置&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/10/ed838fae543dc8d607c231d89fc4888b.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/10/ed838fae543dc8d607c231d89fc4888b.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h3 id=&#34;22-安装并更新-zwift-客户端&#34;&gt;2.2 安装并更新 Zwift 客户端&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;运行刚安装的 Zwift 程序，客户端会开始更新游戏本体
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;⚠️ 重要提示&lt;/strong&gt;：必须在配置网络之前完成此步骤，因为后续配置会修改 hosts 文件，导致无法连接到 Zwift 服务器下载游戏本体&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/734f7507b1e68958bba2ea2525216752.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/734f7507b1e68958bba2ea2525216752.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h3 id=&#34;23-配置网络连接&#34;&gt;2.3 配置网络连接&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;将下载的&lt;code&gt;zoffline-helper.zip&lt;/code&gt;解压到&lt;code&gt;zwiftoffline&lt;/code&gt;目录&lt;/li&gt;
&lt;li&gt;进入&lt;code&gt;zwiftoffline/zoffline-helper&lt;/code&gt;目录&lt;/li&gt;
&lt;li&gt;右键点击&lt;code&gt;configure_client.bat&lt;/code&gt;，选择&lt;strong&gt;以管理员身份运行&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;脚本会自动配置 zoffline，期间会弹窗让你选择 Zwift 安装目录（即之前记住的路径）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/19/52b44adfe177bde733156c3d2faefe5e.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/19/52b44adfe177bde733156c3d2faefe5e.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;配置完成后，会显示如下结果：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/6769deefaa7c142c42411a43af345e8d.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/6769deefaa7c142c42411a43af345e8d.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h3 id=&#34;24-启动并验证&#34;&gt;2.4 启动并验证&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;进入&lt;code&gt;zwiftoffline&lt;/code&gt;目录，双击运行&lt;code&gt;zoffline.exe&lt;/code&gt;（文件名可能因版本而异，如&lt;code&gt;zoffline_1.0.140279.exe&lt;/code&gt;）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/029bd1af360095a4a279b52c822cd5c7.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/029bd1af360095a4a279b52c822cd5c7.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;启动原版 Zwift 程序，检查登录界面
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;成功标志&lt;/strong&gt;：显示 ZwiftOffline 的登录页面（如下图）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/e577c5169d652b1ae201a337a0d292f8.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/e577c5169d652b1ae201a337a0d292f8.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;失败标志&lt;/strong&gt;：如果显示官方原版登录界面，说明配置失败&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/19/d8c93c7c78d2f33555bed4a3be9d671f.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/19/d8c93c7c78d2f33555bed4a3be9d671f.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&lt;strong&gt;⚠️ 重要提示&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;如果显示的是原版登录页面，检查是否开启了代理，关闭代理后重试&lt;/li&gt;
&lt;li&gt;将输入法切换为&lt;strong&gt;微软英文输入法&lt;/strong&gt;，点击&lt;code&gt;Start Zwift&lt;/code&gt;开始游戏&lt;/li&gt;
&lt;li&gt;使用搜狗输入法等第三方输入法可能会卡在登录页面&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;三高级配置&#34;&gt;三、高级配置&lt;/h2&gt;
&lt;h3 id=&#34;31-同步原有账号信息&#34;&gt;3.1 同步原有账号信息&lt;/h3&gt;
&lt;p&gt;如果不配置此项，使用 Zwift offline 时会显示为新账号，而不是你原来的账号信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;配置步骤：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在登录页面点击设置按钮进入设置界面&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/ce3667b3f69bf3ab3fd81c191aee51f8.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/ce3667b3f69bf3ab3fd81c191aee51f8.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;填写你的 Zwift 邮箱和密码，勾选所有选项，点击 Submit 提交&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/9cc77352a1f299516e1f76989bdc60c3.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/9cc77352a1f299516e1f76989bdc60c3.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;配置完成后，再次登录 Zwift 时就会显示为原来的账号了&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;32-配置-strava-自动上传&#34;&gt;3.2 配置 Strava 自动上传&lt;/h3&gt;
&lt;h4 id=&#34;321-申请-strava-api&#34;&gt;3.2.1 申请 Strava API&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;登录&lt;a href=&#34;https://www.strava.com/settings/api&#34;&gt;Strava API 设置页面&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;创建新应用，填写以下信息：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;应用名称&lt;/strong&gt;：自定义（如：ZwiftOffline）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;类别&lt;/strong&gt;：其他&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;授权回调域&lt;/strong&gt;：&lt;code&gt;launcher.zwift.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网站&lt;/strong&gt;：可留空或填写个人网站&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/d8024be9518e5a262538aa5d48c7fbb0.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/d8024be9518e5a262538aa5d48c7fbb0.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;申请完成后，记录下&lt;code&gt;Client ID&lt;/code&gt;和&lt;code&gt;Client Secret&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/a5024f9e2e150810251222315be11ac9.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/a5024f9e2e150810251222315be11ac9.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h4 id=&#34;322-在-zwiftoffline-中配置-strava&#34;&gt;3.2.2 在 ZwiftOffline 中配置 Strava&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在登录页面进入设置，填写&lt;code&gt;Client ID&lt;/code&gt;和&lt;code&gt;Client Secret&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/29afa480ea0c6ceba03f89a14b30c987.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/29afa480ea0c6ceba03f89a14b30c987.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/84b0932cd611d78a1497f82aafa86fb7.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/84b0932cd611d78a1497f82aafa86fb7.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;点击&lt;code&gt;Submit&lt;/code&gt;提交：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/2457689c2493d63ffa77e465948d3d84.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/2457689c2493d63ffa77e465948d3d84.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h4 id=&#34;323-授权-strava-访问&#34;&gt;3.2.3 授权 Strava 访问&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;这一步可以省略，如果通过上面的步骤没法上传，再尝试这个步骤手动配置&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;右键以管理员身份运行&lt;code&gt;zoffline-helper/disable_zoffline.bat&lt;/code&gt;，清除 hosts 配置&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在命令行中运行以下命令（替换&lt;code&gt;CLIENT_ID&lt;/code&gt;和&lt;code&gt;CLIENT_SECRET&lt;/code&gt;为你的实际值）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;zoffline-helper/strava_auth.exe --client-id CLIENT_ID --client-secret CLIENT_SECRET
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器会自动打开或手动访问&lt;code&gt;localhost:8000&lt;/code&gt;进行授权&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/05/18/4b0dbbd3bd2dd82b1c6da8327e494ea3.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/05/18/4b0dbbd3bd2dd82b1c6da8327e494ea3.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/05/18/05c02cfd9cd98aaf1e198d2f99b58f5a.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/05/18/05c02cfd9cd98aaf1e198d2f99b58f5a.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;授权完成后，将生成的&lt;code&gt;strava_token.txt&lt;/code&gt;文件移动到&lt;code&gt;storage/1&lt;/code&gt;目录下&lt;/li&gt;
&lt;li&gt;右键以管理员身份运行&lt;code&gt;zoffline-helper/configure_client.bat&lt;/code&gt;，重新配置 hosts&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;33-上传自定义训练课程&#34;&gt;3.3 上传自定义训练课程&lt;/h3&gt;
&lt;p&gt;如果你习惯在 Intervals ICU 等平台创建训练课程，可以手动上传到 Zwift 单机版。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上传步骤：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;将你的&lt;code&gt;.zwo&lt;/code&gt;训练课程文件保存到以下目录：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Documents/Zwift/Workouts/1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/15/f18d29b2d3e548bf2fe0878d54b2f45f.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/15/f18d29b2d3e548bf2fe0878d54b2f45f.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&lt;strong&gt;⚠️ 注意&lt;/strong&gt;：不是&lt;code&gt;zwiftoffline\storage\1\customworkouts&lt;/code&gt;目录，如果放错位置会导致课程无法上传&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/15/edd5d0ab56c733e794d196838851dfe3.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/15/edd5d0ab56c733e794d196838851dfe3.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h3 id=&#34;34-配置-garmin-connect&#34;&gt;3.4 配置 Garmin Connect&lt;/h3&gt;
&lt;p&gt;Garmin Connect 可以同步你的 Zwift 活动数据到 Garmin 设备。&lt;/p&gt;
&lt;h4 id=&#34;341-配置账号&#34;&gt;3.4.1 配置账号&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PC 端配置&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 ZwiftOffline 登录窗口点击&amp;quot;Settings - Garmin&amp;quot;按钮&lt;/li&gt;
&lt;li&gt;输入你的 Garmin Connect 账号和密码&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安卓端配置&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;访问 &lt;code&gt;https://&amp;lt;zoffline_ip&amp;gt;/garmin/zoffline/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;输入你的 Garmin Connect 账号和密码&lt;/li&gt;
&lt;li&gt;将&lt;code&gt;&amp;lt;zoffline_ip&amp;gt;&lt;/code&gt;替换为运行 zoffline 的电脑 IP 地址&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;342-多因素认证mfa&#34;&gt;3.4.2 多因素认证（MFA）&lt;/h4&gt;
&lt;p&gt;如果你的账号启用了多因素认证，需要额外配置：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用 Python 脚本（推荐）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;运行&lt;code&gt;garmin_auth.py&lt;/code&gt;脚本&lt;/li&gt;
&lt;li&gt;脚本会在运行目录下生成&lt;code&gt;garth&lt;/code&gt;文件夹&lt;/li&gt;
&lt;li&gt;将&lt;code&gt;garth&lt;/code&gt;文件夹移动到&lt;code&gt;storage/1&lt;/code&gt;目录下&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用 Windows 可执行文件&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果未安装 Python，可以从&lt;a href=&#34;https://github.com/oldnapalm/zoffline-helper/releases/latest&#34;&gt;zoffline-helper Release 页面&lt;/a&gt;下载&lt;code&gt;garmin_auth.exe&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;运行&lt;code&gt;garmin_auth.exe&lt;/code&gt;，同样会生成&lt;code&gt;garth&lt;/code&gt;文件夹&lt;/li&gt;
&lt;li&gt;将&lt;code&gt;garth&lt;/code&gt;文件夹移动到&lt;code&gt;storage/1&lt;/code&gt;目录下&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;35-配置-intervalsicu&#34;&gt;3.5 配置 Intervals.icu&lt;/h3&gt;
&lt;p&gt;Intervals.icu 是一个强大的训练分析平台，可以同步 Zwift 活动数据。&lt;/p&gt;
&lt;h4 id=&#34;351-获取-api-凭证&#34;&gt;3.5.1 获取 API 凭证&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;登录 &lt;a href=&#34;https://intervals.icu/settings&#34;&gt;Intervals.icu 设置页面&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;进入&amp;quot;Developer Settings&amp;quot;（开发者设置）部分&lt;/li&gt;
&lt;li&gt;复制以下信息：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Athlete ID&lt;/strong&gt;（运动员 ID）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Key&lt;/strong&gt;（API 密钥）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;352-配置账号&#34;&gt;3.5.2 配置账号&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PC 端配置&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 ZwiftOffline 登录窗口点击&amp;quot;Settings - Intervals&amp;quot;按钮&lt;/li&gt;
&lt;li&gt;输入之前复制的 Athlete ID 和 API Key&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安卓端配置&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;访问 &lt;code&gt;https://&amp;lt;zoffline_ip&amp;gt;/intervals/zoffline/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;输入 Athlete ID 和 API Key&lt;/li&gt;
&lt;li&gt;将&lt;code&gt;&amp;lt;zoffline_ip&amp;gt;&lt;/code&gt;替换为运行 zoffline 的电脑 IP 地址&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;36-启用多人游戏&#34;&gt;3.6 启用多人游戏&lt;/h3&gt;
&lt;p&gt;多人游戏功能允许多个用户同时连接到同一个 zoffline 服务器进行骑行。&lt;/p&gt;
&lt;h4 id=&#34;361-基本配置&#34;&gt;3.6.1 基本配置&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;multiplayer.txt&lt;/code&gt;文件（文件内容为空）&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;362-远程服务器配置&#34;&gt;3.6.2 远程服务器配置&lt;/h4&gt;
&lt;p&gt;如果 zoffline 运行在与 Zwift 客户端不同的 PC 上：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;server-ip.txt&lt;/code&gt;文件&lt;/li&gt;
&lt;li&gt;文件内容填写运行 zoffline 的 PC 的 IP 地址&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;端口要求&lt;/strong&gt;：确保以下端口在运行 zoffline 的 PC 上开放：
&lt;ul&gt;
&lt;li&gt;TCP 端口：80, 443, 3025&lt;/li&gt;
&lt;li&gt;UDP 端口：3024&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;363-创建账号&#34;&gt;3.6.3 创建账号&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;启动 Zwift，创建新账号&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;⚠️ 注意&lt;/strong&gt;：此账号仅存在于你的 zoffline 服务器上，与官方 Zwift 账号无关&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;364-启用密码重置功能可选&#34;&gt;3.6.4 启用密码重置功能（可选）&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;gmail_credentials.txt&lt;/code&gt;文件&lt;/li&gt;
&lt;li&gt;文件内容格式：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;gmail 账号&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;应用密码&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;恢复 URL 主机（可选）&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&lt;strong&gt;获取应用密码&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;访问 &lt;a href=&#34;https://security.google.com/settings/security/apppasswords&#34;&gt;https://security.google.com/settings/security/apppasswords&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;创建应用密码，允许服务器登录&lt;/li&gt;
&lt;li&gt;将生成的应用密码填入文件第二行&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;恢复 URL 主机&lt;/strong&gt;（可选）：
&lt;ul&gt;
&lt;li&gt;第三行可以填写恢复 URL 的主机地址&lt;/li&gt;
&lt;li&gt;如果不填写，将使用服务器 IP 地址作为默认值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;37-启用-ghosts幽灵&#34;&gt;3.7 启用 Ghosts（幽灵）&lt;/h3&gt;
&lt;p&gt;Ghosts 功能可以保存你之前的骑行记录，并在相同路线上显示为&amp;quot;幽灵&amp;quot;与你一起骑行。&lt;/p&gt;
&lt;h4 id=&#34;371-启用功能&#34;&gt;3.7.1 启用功能&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PC 端&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 zoffline 启动器窗口中勾选&amp;quot;Enable ghosts&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安卓端&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;访问 &lt;code&gt;https://&amp;lt;zoffline_ip&amp;gt;/user/zoffline/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;勾选&amp;quot;Enable ghosts&amp;quot;&lt;/li&gt;
&lt;li&gt;点击&amp;quot;Start Zwift&amp;quot;保存设置&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;372-使用说明&#34;&gt;3.7.2 使用说明&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;保存幽灵&lt;/strong&gt;：当你保存活动时，幽灵会自动保存在&lt;code&gt;storage/&amp;lt;player_id&amp;gt;/ghosts/&amp;lt;world&amp;gt;/&amp;lt;route&amp;gt;&lt;/code&gt;目录下&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;加载幽灵&lt;/strong&gt;：下次骑行相同路线时，幽灵会自动加载&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重新编组&lt;/strong&gt;：在聊天中输入&lt;code&gt;.regroup&lt;/code&gt;命令可以重新编组幽灵&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;373-自定义装备&#34;&gt;3.7.3 自定义装备&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;ghost_profile.txt&lt;/code&gt;文件&lt;/li&gt;
&lt;li&gt;可以使用&lt;code&gt;find_equip.py&lt;/code&gt;脚本来自动填充此文件&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;38-启用-bots机器人&#34;&gt;3.8 启用 Bots（机器人）&lt;/h3&gt;
&lt;p&gt;Bots 功能可以将保存的幽灵转换为持续骑行的机器人，无论你选择什么路线，它们都会继续骑行。&lt;/p&gt;
&lt;h4 id=&#34;381-启用功能&#34;&gt;3.8.1 启用功能&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;enable_bots.txt&lt;/code&gt;文件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可选&lt;/strong&gt;：文件内容可以包含一个倍数（如：&lt;code&gt;2&lt;/code&gt;表示双倍机器人数量）
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;⚠️ 警告&lt;/strong&gt;：如果机器人数量过多，可能导致性能问题或功能失效&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;382-控制命令&#34;&gt;3.8.2 控制命令&lt;/h4&gt;
&lt;p&gt;在聊天中使用以下命令控制机器人：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.group&lt;/code&gt;：编组机器人&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.groupall&lt;/code&gt;：编组所有机器人（包括使用倍数时的重复机器人）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.autogroup&lt;/code&gt;：自动编组（当你改变路线时）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.autogroupall&lt;/code&gt;：自动编组所有机器人&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.stopautogroup&lt;/code&gt;：停止自动编组&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.disperse&lt;/code&gt;：随机化机器人位置&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;383-自定义机器人&#34;&gt;3.8.3 自定义机器人&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;bot.txt&lt;/code&gt;文件&lt;/li&gt;
&lt;li&gt;可以自定义机器人的名称、国籍和装备&lt;/li&gt;
&lt;li&gt;可以使用&lt;code&gt;get_pro_names.py&lt;/code&gt;脚本来自动填充此文件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;随机机器人&lt;/strong&gt;：如果需要随机机器人，可以参考&lt;a href=&#34;https://github.com/oldnapalm/zoffline-bots&#34;&gt;zoffline-bots 仓库&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;39-配置-robopacers机器人配速员&#34;&gt;3.9 配置 RoboPacers（机器人配速员）&lt;/h3&gt;
&lt;p&gt;RoboPacers 是使用功率模拟器保存的幽灵，可以创建完美的循环配速员。&lt;/p&gt;
&lt;h4 id=&#34;391-获取-robopacers&#34;&gt;3.9.1 获取 RoboPacers&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;可以从&lt;a href=&#34;https://github.com/oldnapalm/zoffline-bots&#34;&gt;zoffline-bots 仓库&lt;/a&gt;下载预制的 RoboPacers&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;392-创建要求&#34;&gt;3.9.2 创建要求&lt;/h4&gt;
&lt;p&gt;要创建可用的 RoboPacer，需要满足以下条件：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;更新频率&lt;/strong&gt;：必须使用 1 秒的更新频率录制（默认是 3 秒）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;循环要求&lt;/strong&gt;：活动必须从同一位置和速度开始和结束，否则机器人无法平滑循环&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置文件要求&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;必须包含唯一的玩家 ID&lt;/li&gt;
&lt;li&gt;必须包含路线 ID&lt;/li&gt;
&lt;li&gt;这样当你加入机器人时，会在交叉路口走相同的转弯&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;393-编辑工具&#34;&gt;3.9.3 编辑工具&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;bot_editor.py 脚本&lt;/strong&gt;：可以用于修改以下文件：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;profile.bin&lt;/code&gt;：设置名称、玩家 ID 和路线 ID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;route.bin&lt;/code&gt;：裁剪多余的点以创建完美循环&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;394-创建动态-robopacer&#34;&gt;3.9.4 创建动态 RoboPacer&lt;/h4&gt;
&lt;p&gt;要创建动态 RoboPacer（在上坡时增加功率，下坡时减少功率）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用 &lt;a href=&#34;https://github.com/oldnapalm/zwift-offline/blob/master/standalone_power.py&#34;&gt;standalone_power.py&lt;/a&gt; 脚本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;硬件要求&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;2 个 ANT 适配器&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mch/python-ant&#34;&gt;python-ant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/oldnapalm/zwift-offline/blob/master/PowerMeterTx.py&#34;&gt;PowerMeterTx.py&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;310-使用-bookmarks书签&#34;&gt;3.10 使用 Bookmarks（书签）&lt;/h3&gt;
&lt;p&gt;书签功能可以保存你的位置，方便快速跳转到特定地点。&lt;/p&gt;
&lt;h4 id=&#34;3101-自动保存书签&#34;&gt;3.10.1 自动保存书签&lt;/h4&gt;
&lt;p&gt;当你完成活动时，你的最后位置会自动保存为书签。&lt;/p&gt;
&lt;h4 id=&#34;3102-手动保存书签&#34;&gt;3.10.2 手动保存书签&lt;/h4&gt;
&lt;p&gt;在聊天中使用以下命令保存书签：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.bookmark &amp;lt;名称&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;例如：&lt;code&gt;.bookmark 起点&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;3103-使用书签&#34;&gt;3.10.3 使用书签&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;从书签开始新活动&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在主页屏幕选择&amp;quot;Join a Zwifter&amp;quot;&lt;/li&gt;
&lt;li&gt;选择你想要的书签&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;传送到书签&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用操作栏上的传送图标&lt;/li&gt;
&lt;li&gt;选择目标书签进行传送&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;311-启用历史排行榜&#34;&gt;3.11 启用历史排行榜&lt;/h3&gt;
&lt;p&gt;历史排行榜功能可以覆盖 60 分钟的实时结果和 90 天的个人记录，显示所有时间的最佳成绩。&lt;/p&gt;
&lt;h4 id=&#34;3111-启用功能&#34;&gt;3.11.1 启用功能&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;all_time_leaderboards.txt&lt;/code&gt;文件（文件内容可以为空）&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;3112-功能说明&#34;&gt;3.11.2 功能说明&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;排行榜&lt;/strong&gt;：显示所有时间的最佳成绩，而不仅仅是最近 60 分钟或 90 天的记录&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;荣誉衫&lt;/strong&gt;：仍然有效期为 60 分钟，但只有在创造新的历史记录时才会授予&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;312-解锁装备&#34;&gt;3.12 解锁装备&lt;/h3&gt;
&lt;p&gt;可以解锁特殊装备或所有装备。&lt;/p&gt;
&lt;h4 id=&#34;3121-解锁特殊装备&#34;&gt;3.12.1 解锁特殊装备&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;unlock_entitlements.txt&lt;/code&gt;文件（文件内容可以为空）&lt;/li&gt;
&lt;li&gt;这将解锁需要特殊权限的装备&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;3122-解锁所有装备&#34;&gt;3.12.2 解锁所有装备&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;unlock_all_equipment.txt&lt;/code&gt;文件（文件内容可以为空）&lt;/li&gt;
&lt;li&gt;这将解锁所有可用装备&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;313-配置-cdn-代理&#34;&gt;3.13 配置 CDN 代理&lt;/h3&gt;
&lt;p&gt;CDN 代理功能可以从 Zwift 官方服务器获取地图时间表和更新文件。&lt;/p&gt;
&lt;h4 id=&#34;3131-启用-cdn-代理&#34;&gt;3.13.1 启用 CDN 代理&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;cdn-proxy.txt&lt;/code&gt;文件（文件内容可以为空）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;⚠️ 限制&lt;/strong&gt;：此功能只能在 zoffline 运行在与 Zwift 客户端不同的机器上时使用&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;3132-禁用代理&#34;&gt;3.13.2 禁用代理&lt;/h4&gt;
&lt;p&gt;默认情况下，zoffline 会尝试使用 Google 公共 DNS 来解析 Zwift 主机名，即使 zoffline 与 Zwift 客户端运行在同一台机器上也能工作。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果要禁用此代理功能，在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;disable_proxy.txt&lt;/code&gt;文件&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;3133-从-zoffline-提供更新文件&#34;&gt;3.13.3 从 zoffline 提供更新文件&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;运行&lt;code&gt;get_gameassets.py&lt;/code&gt;脚本下载游戏文件&lt;/li&gt;
&lt;li&gt;这样 zoffline 可以直接提供更新文件，而不需要从 Zwift 服务器获取&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;四移动端-companion-配置&#34;&gt;四、移动端 Companion 配置&lt;/h2&gt;
&lt;p&gt;Zwift Companion 是配套的移动端社交软件，可用于与骑友互动、配对设备、点赞、使用道具等功能。使用离线版 Zwift 需要重新打包 Companion 应用。&lt;/p&gt;
&lt;h3 id=&#34;41-准备工作&#34;&gt;4.1 准备工作&lt;/h3&gt;
&lt;p&gt;官方原版 Companion 会对网络连接和证书做严格验证，需要对其进行&amp;quot;打补丁并重签名&amp;quot;才能连接到本地 zoffline 服务器。&lt;/p&gt;
&lt;h3 id=&#34;42-替换-apk-证书并重新签名&#34;&gt;4.2 替换 APK 证书并重新签名&lt;/h3&gt;
&lt;h4 id=&#34;421-安装-apk-mitm&#34;&gt;4.2.1 安装 apk-mitm&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;安装 Node.js（如果尚未安装）&lt;/li&gt;
&lt;li&gt;使用以下命令全局安装 apk-mitm：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g apk-mitm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;其他系统可参考&lt;a href=&#34;https://github.com/shroudedcode/apk-mitm&#34;&gt;apk-mitm 项目 README&lt;/a&gt;自行安装&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;422-修改-apktool-配置&#34;&gt;4.2.2 修改 apktool 配置&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;使用&lt;code&gt;npm root -g&lt;/code&gt;查找 apk-mitm 的实际安装路径&lt;/li&gt;
&lt;li&gt;打开&lt;code&gt;apk-mitm/dist/tools/apktool.js&lt;/code&gt;文件&lt;/li&gt;
&lt;li&gt;修改&lt;code&gt;decode&lt;/code&gt;方法，添加&lt;code&gt;-resm&lt;/code&gt;和&lt;code&gt;dummy&lt;/code&gt;参数：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;inputPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;outputPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s1&#34;&gt;&amp;#39;decode&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s1&#34;&gt;&amp;#39;-resm&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// add this
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s1&#34;&gt;&amp;#39;dummy&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// add this
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nx&#34;&gt;inputPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s1&#34;&gt;&amp;#39;--output&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nx&#34;&gt;outputPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s1&#34;&gt;&amp;#39;--frame-path&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;frameworkPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;decoding&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;423-生成修改后的-apk&#34;&gt;4.2.3 生成修改后的 APK&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;从&lt;a href=&#34;https://github.com/zoffline/zwift-offline&#34;&gt;Zwift Offline 仓库&lt;/a&gt;下载以下文件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ssl/cert-zwift-com.pem&lt;/code&gt;（证书文件）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;zwift-offline-companion.apk&lt;/code&gt;（原始 APK 文件）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将这两个文件复制到同一目录（如：&lt;code&gt;C:\Users\Administrator\Desktop\zwift-offline-companion&lt;/code&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在该目录下运行以下命令：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;apk-mitm --certificate cert-zwift-com.pem zwift-offline-companion.apk
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;命令执行完成后，会生成&lt;code&gt;zwift-offline-companion-patched.apk&lt;/code&gt;文件，将其拷贝到手机安装即可&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;43-配置域名重定向&#34;&gt;4.3 配置域名重定向&lt;/h3&gt;
&lt;h4 id=&#34;431-安装-virtual-hosts&#34;&gt;4.3.1 安装 Virtual Hosts&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;下载&lt;a href=&#34;https://github.com/x-falcon/Virtual-Hosts/releases/latest&#34;&gt;virtual hosts&lt;/a&gt;软件&lt;/li&gt;
&lt;li&gt;安装到手机中&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;432-创建-hosts-文件&#34;&gt;4.3.2 创建 hosts 文件&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;创建&lt;code&gt;hosts.txt&lt;/code&gt;文件，内容如下（将&lt;code&gt;&amp;lt;zoffline ip&amp;gt;&lt;/code&gt;替换为你运行 zoffline 的电脑 IP 地址）：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;zoffline ip&amp;gt; us-or-rly101.zwift.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;zoffline ip&amp;gt; secure.zwift.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&lt;strong&gt;⚠️ 重要提示&lt;/strong&gt;：如果在 PC 上配置过 hosts 文件，可能包含以下映射：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;127.0.0.1 cdn.zwift.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;此映射不要添加到手机端的 hosts 文件中！&lt;/strong&gt;&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;将&lt;code&gt;hosts.txt&lt;/code&gt;文件复制到手机，放在便于访问的位置&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;433-启用域名重定向&#34;&gt;4.3.3 启用域名重定向&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;打开 Virtual Hosts 软件&lt;/li&gt;
&lt;li&gt;选择之前创建的&lt;code&gt;hosts.txt&lt;/code&gt;文件&lt;/li&gt;
&lt;li&gt;启用域名重定向功能&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;44-使用-companion&#34;&gt;4.4 使用 Companion&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;使用离线版的账号登录 Companion，即可正常使用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;验证连接&lt;/strong&gt;：在打开和登录 Companion 时，观察 PC 端运行的 Zwift offline 命令行窗口是否有日志输出
&lt;ul&gt;
&lt;li&gt;如果有日志输出，说明连接正常&lt;/li&gt;
&lt;li&gt;如果没有任何输出，说明请求未成功转发，需要检查 IP 地址配置是否正确&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;五安卓设备直接使用-zwift-offline&#34;&gt;五、安卓设备直接使用 Zwift Offline&lt;/h2&gt;
&lt;p&gt;除了在 PC 上使用 Zwift Offline，你也可以直接在安卓设备上运行 Zwift 并连接到 zoffline 服务器。这种方式不需要 root 权限，但需要在每次安装或更新 Zwift 后重新打补丁。&lt;/p&gt;
&lt;h3 id=&#34;51-安装必要应用&#34;&gt;5.1 安装必要应用&lt;/h3&gt;
&lt;h4 id=&#34;511-下载并安装-zofflineobb&#34;&gt;5.1.1 下载并安装 ZofflineObb&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;从&lt;a href=&#34;https://github.com/Argon2000/ZofflineObbAndroid/releases/latest&#34;&gt;GitHub Release 页面&lt;/a&gt;下载&lt;code&gt;ZofflineObb.apk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;安装到安卓设备上（需要允许安装未知来源应用）&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;512-下载并安装-virtual-hosts&#34;&gt;5.1.2 下载并安装 Virtual Hosts&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;从&lt;a href=&#34;https://github.com/x-falcon/Virtual-Hosts/releases/latest&#34;&gt;GitHub Release 页面&lt;/a&gt;下载&lt;code&gt;app-Github-release.apk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;安装到安卓设备上&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;52-配置域名重定向&#34;&gt;5.2 配置域名重定向&lt;/h3&gt;
&lt;h4 id=&#34;521-创建-hoststxt-文件&#34;&gt;5.2.1 创建 hosts.txt 文件&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;创建&lt;code&gt;hosts.txt&lt;/code&gt;文件，可以使用文本编辑器应用或在线工具（如&lt;a href=&#34;https://passwordsgenerator.net/text-editor/&#34;&gt;在线文本编辑器&lt;/a&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;文件内容如下（将&lt;code&gt;&amp;lt;zoffline ip&amp;gt;&lt;/code&gt;替换为运行 zoffline 的电脑 IP 地址）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;zoffline ip&amp;gt; us-or-rly101.zwift.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;zoffline ip&amp;gt; secure.zwift.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;zoffline ip&amp;gt; cdn.zwift.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;⚠️ 注意&lt;/strong&gt;：与 Companion 配置不同，安卓设备直接使用需要包含&lt;code&gt;cdn.zwift.com&lt;/code&gt;的映射&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将&lt;code&gt;hosts.txt&lt;/code&gt;文件保存到手机，放在便于访问的位置&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;522-关闭-private-dns&#34;&gt;5.2.2 关闭 Private DNS&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;进入安卓设备的&lt;strong&gt;设置&lt;/strong&gt; &amp;gt; &lt;strong&gt;网络和互联网&lt;/strong&gt; &amp;gt; &lt;strong&gt;高级&lt;/strong&gt; &amp;gt; &lt;strong&gt;Private DNS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;选择&lt;strong&gt;关闭&lt;/strong&gt;或&lt;strong&gt;自动&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;523-配置-virtual-hosts&#34;&gt;5.2.3 配置 Virtual Hosts&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;打开 Virtual Hosts 应用&lt;/li&gt;
&lt;li&gt;选择之前创建的&lt;code&gt;hosts.txt&lt;/code&gt;文件&lt;/li&gt;
&lt;li&gt;启用域名重定向功能（确保按钮处于开启状态）&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;524-替代方案使用-dns-配置&#34;&gt;5.2.4 替代方案：使用 DNS 配置&lt;/h4&gt;
&lt;p&gt;如果你不想使用 Virtual Hosts 应用，也可以使用以下方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在运行 zoffline 的 PC 上，在&lt;code&gt;storage&lt;/code&gt;目录下创建&lt;code&gt;fake-dns.txt&lt;/code&gt;文件&lt;/li&gt;
&lt;li&gt;在手机的 Wi-Fi 设置中，将&lt;strong&gt;DNS 1&lt;/strong&gt;设置为运行 zoffline 的 PC 的 IP 地址&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：如果你的路由器支持，也可以在路由器层面配置 DNS 记录，这样所有设备都可以自动使用&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;53-安装并打补丁-zwift&#34;&gt;5.3 安装并打补丁 Zwift&lt;/h3&gt;
&lt;h4 id=&#34;531-安装-zwift&#34;&gt;5.3.1 安装 Zwift&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;从 Google Play 商店安装或更新 Zwift&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;⚠️ 重要&lt;/strong&gt;：安装或更新后，&lt;strong&gt;不要立即启动&lt;/strong&gt; Zwift&lt;/li&gt;
&lt;li&gt;如果已经启动过 Zwift，需要先清除数据：
&lt;ul&gt;
&lt;li&gt;进入&lt;strong&gt;设置&lt;/strong&gt; &amp;gt; &lt;strong&gt;应用&lt;/strong&gt; &amp;gt; &lt;strong&gt;Zwift&lt;/strong&gt; &amp;gt; &lt;strong&gt;存储&lt;/strong&gt; &amp;gt; &lt;strong&gt;清除数据&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;或者卸载后重新安装&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;532-运行-zofflineobb-打补丁&#34;&gt;5.3.2 运行 ZofflineObb 打补丁&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;打开&lt;code&gt;ZofflineObb&lt;/code&gt;应用&lt;/li&gt;
&lt;li&gt;运行补丁程序（允许访问存储权限）&lt;/li&gt;
&lt;li&gt;等待补丁过程完成（通常需要 5-10 分钟）&lt;/li&gt;
&lt;li&gt;补丁完成后，应用会提示完成&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;原理说明&lt;/strong&gt;：ZofflineObb 会修改 Zwift 应用，使其接受 zoffline 服务器的自签名证书，这是连接离线服务器的关键步骤。&lt;/p&gt;
&lt;h3 id=&#34;54-运行-zwift&#34;&gt;5.4 运行 Zwift&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;确保 Virtual Hosts 按钮处于开启状态&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;启动 Zwift 应用&lt;/li&gt;
&lt;li&gt;使用任意邮箱和密码登录，或创建新用户（如果启用了多人游戏功能）&lt;/li&gt;
&lt;li&gt;Zwift 应该能够正常验证下载并运行&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;55-重要提示&#34;&gt;5.5 重要提示&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;每次更新后需要重新打补丁&lt;/strong&gt;：无论是从 Google Play 更新 Zwift，还是重新安装，都需要重新运行 ZofflineObb 打补丁&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保持网络连接&lt;/strong&gt;：确保安卓设备与运行 zoffline 的 PC 在同一局域网内&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;防火墙设置&lt;/strong&gt;：确保 PC 的防火墙允许 zoffline 的端口访问&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;六常见问题&#34;&gt;六、常见问题&lt;/h2&gt;
&lt;h3 id=&#34;61-卡在蓝色登录界面&#34;&gt;6.1 卡在蓝色登录界面&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;症状：&lt;/strong&gt; 登录时卡在蓝色界面，无法进入游戏&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/20/03f08f3fa8d593d33b38647a46f22341.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/20/03f08f3fa8d593d33b38647a46f22341.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方法：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在任务管理器中关闭 Zwift 进程&lt;/li&gt;
&lt;li&gt;将输入法切换为&lt;strong&gt;微软英文输入法&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;重新启动 Zwift 并登录&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/20/48a6263e5ffe475ec5753b13cffd2ec1.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/20/48a6263e5ffe475ec5753b13cffd2ec1.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h3 id=&#34;62-配置后无法更新-zwift&#34;&gt;6.2 配置后无法更新 Zwift&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;原因：&lt;/strong&gt; &lt;code&gt;configure_client.bat&lt;/code&gt;会修改 Hosts 文件，导致无法连接到 Zwift 服务器&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方法：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;关闭正在运行的&lt;code&gt;zoffline&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;进入&lt;code&gt;zwiftoffline/zoffline-helper&lt;/code&gt;目录&lt;/li&gt;
&lt;li&gt;右键点击&lt;code&gt;disable_zoffline.bat&lt;/code&gt;，选择&lt;strong&gt;以管理员身份运行&lt;/strong&gt;，清除网络配置&lt;/li&gt;
&lt;li&gt;打开 Zwift 进行更新&lt;/li&gt;
&lt;li&gt;更新完成后，重新运行&lt;code&gt;configure_client.bat&lt;/code&gt;恢复配置&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;63-无法自动上传活动到-strava&#34;&gt;6.3 无法自动上传活动到 Strava&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;可能原因及解决方法：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;检查&lt;code&gt;strava_token.txt&lt;/code&gt;文件是否已正确放置在&lt;code&gt;storage/1&lt;/code&gt;目录下&lt;/li&gt;
&lt;li&gt;确认 Strava API 的&lt;code&gt;Client ID&lt;/code&gt;和&lt;code&gt;Client Secret&lt;/code&gt;配置正确&lt;/li&gt;
&lt;li&gt;检查网络连接，确保 zoffline 可以访问 Strava API&lt;/li&gt;
&lt;li&gt;查看 zoffline 命令行窗口的错误日志，根据具体错误信息进行排查&lt;/li&gt;
&lt;li&gt;检查在申请 API 时填写的授权回调域是否正确&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;64-安卓客户端无法登录&#34;&gt;6.4 安卓客户端无法登录&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;可能原因及解决方法：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对于 Companion 应用：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;检查 Virtual Hosts 是否已正确启用&lt;/li&gt;
&lt;li&gt;确认 hosts 文件中的 IP 地址是否正确（应为运行 zoffline 的电脑 IP，而非 127.0.0.1）&lt;/li&gt;
&lt;li&gt;确保手机和电脑在同一局域网内&lt;/li&gt;
&lt;li&gt;检查防火墙设置，确保 zoffline 的端口未被阻止&lt;/li&gt;
&lt;li&gt;重新安装修改后的 APK 文件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;对于直接使用 Zwift 应用：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;确认已关闭 Private DNS 设置&lt;/li&gt;
&lt;li&gt;检查 Virtual Hosts 是否已正确启用，按钮必须处于开启状态&lt;/li&gt;
&lt;li&gt;确认 hosts.txt 文件包含所有三个域名映射（包括&lt;code&gt;cdn.zwift.com&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;检查是否在安装/更新 Zwift 后运行了 ZofflineObb 打补丁&lt;/li&gt;
&lt;li&gt;如果已启动过 Zwift，尝试清除应用数据后重新打补丁&lt;/li&gt;
&lt;li&gt;确认手机和运行 zoffline 的 PC 在同一局域网内&lt;/li&gt;
&lt;li&gt;检查 PC 防火墙设置，确保 zoffline 端口未被阻止&lt;/li&gt;
&lt;/ol&gt;
</description>
      <content:encoded><![CDATA[<h2 id="前言">前言</h2>
<p><a href="https://github.com/zoffline/zwift-offline?tab=readme-ov-file">ZwiftOffline</a>是一个开源社区自制的 Zwift 的 server 端，可以在没有网络的情况下进行 Zwift 课程或路线训练，多平台支持。</p>
<p>本教程将详细介绍如何在 Windows 系统上安装和配置 Zwift 单机版，包括基础安装、账号配置、Strava 同步、训练课程上传以及移动端 Companion 配置等完整流程。</p>
<h2 id="一准备工作">一、准备工作</h2>
<h3 id="11-下载必要文件">1.1 下载必要文件</h3>
<ol>
<li>
<p><strong>ZwiftOffline 主程序</strong></p>
<ul>
<li>从<a href="https://github.com/zoffline/zwift-offline/releases/latest">GitHub Release 页面</a>下载最新的 zoffline 发布版（<code>.exe</code>文件）</li>
</ul>
</li>
<li>
<p><strong>配置辅助工具</strong></p>
<ul>
<li>从<a href="https://github.com/oldnapalm/zoffline-helper/releases/latest">GitHub Release</a>下载<code>zoffline-helper.zip</code>配置脚本文件</li>
</ul>
</li>
<li>
<p><strong>Zwift 官方客户端</strong></p>
<ul>
<li>前往<a href="https://www.zwift.com/">Zwift 官网</a>，拉到页面底部，下载并安装 Zwift 软件</li>
<li><strong>重要</strong>：记住安装路径，后续配置需要用到（例如：<code>C:\Program Files (x86)\Zwift</code>）</li>
</ul>
</li>
</ol>
<h3 id="12-创建运行目录">1.2 创建运行目录</h3>
<p>创建一个目录用于存放 ZwiftOffline 相关文件，例如新建<code>zwiftoffline</code>目录。</p>
<h2 id="二基础安装与配置">二、基础安装与配置</h2>
<h3 id="21-初始化-zwiftoffline">2.1 初始化 ZwiftOffline</h3>
<ol>
<li>将下载的<code>zoffline.exe</code>文件保存到<code>zwiftoffline</code>目录</li>
<li>运行<code>zoffline.exe</code>，程序会在同目录下自动创建<code>storage</code>目录（用于保存 Zwift 进度）</li>
<li>看到<code>storage</code>目录生成后，按<code>Ctrl+C</code>关闭 zoffline，稍后进行配置</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/10/ed838fae543dc8d607c231d89fc4888b.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/10/ed838fae543dc8d607c231d89fc4888b.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h3 id="22-安装并更新-zwift-客户端">2.2 安装并更新 Zwift 客户端</h3>
<ol>
<li>运行刚安装的 Zwift 程序，客户端会开始更新游戏本体
<ul>
<li><strong>⚠️ 重要提示</strong>：必须在配置网络之前完成此步骤，因为后续配置会修改 hosts 文件，导致无法连接到 Zwift 服务器下载游戏本体</li>
</ul>
</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/734f7507b1e68958bba2ea2525216752.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/734f7507b1e68958bba2ea2525216752.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h3 id="23-配置网络连接">2.3 配置网络连接</h3>
<ol>
<li>将下载的<code>zoffline-helper.zip</code>解压到<code>zwiftoffline</code>目录</li>
<li>进入<code>zwiftoffline/zoffline-helper</code>目录</li>
<li>右键点击<code>configure_client.bat</code>，选择<strong>以管理员身份运行</strong></li>
<li>脚本会自动配置 zoffline，期间会弹窗让你选择 Zwift 安装目录（即之前记住的路径）</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/19/52b44adfe177bde733156c3d2faefe5e.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/19/52b44adfe177bde733156c3d2faefe5e.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<ol start="5">
<li>配置完成后，会显示如下结果：</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/6769deefaa7c142c42411a43af345e8d.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/6769deefaa7c142c42411a43af345e8d.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h3 id="24-启动并验证">2.4 启动并验证</h3>
<ol>
<li>进入<code>zwiftoffline</code>目录，双击运行<code>zoffline.exe</code>（文件名可能因版本而异，如<code>zoffline_1.0.140279.exe</code>）</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/029bd1af360095a4a279b52c822cd5c7.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/029bd1af360095a4a279b52c822cd5c7.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<ol start="2">
<li>启动原版 Zwift 程序，检查登录界面
<ul>
<li><strong>成功标志</strong>：显示 ZwiftOffline 的登录页面（如下图）</li>
</ul>
</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/e577c5169d652b1ae201a337a0d292f8.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/e577c5169d652b1ae201a337a0d292f8.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<ul>
<li><strong>失败标志</strong>：如果显示官方原版登录界面，说明配置失败</li>
</ul>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/19/d8c93c7c78d2f33555bed4a3be9d671f.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/19/d8c93c7c78d2f33555bed4a3be9d671f.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<ol start="3">
<li><strong>⚠️ 重要提示</strong>：
<ul>
<li>如果显示的是原版登录页面，检查是否开启了代理，关闭代理后重试</li>
<li>将输入法切换为<strong>微软英文输入法</strong>，点击<code>Start Zwift</code>开始游戏</li>
<li>使用搜狗输入法等第三方输入法可能会卡在登录页面</li>
</ul>
</li>
</ol>
<h2 id="三高级配置">三、高级配置</h2>
<h3 id="31-同步原有账号信息">3.1 同步原有账号信息</h3>
<p>如果不配置此项，使用 Zwift offline 时会显示为新账号，而不是你原来的账号信息。</p>
<p><strong>配置步骤：</strong></p>
<ol>
<li>在登录页面点击设置按钮进入设置界面</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/ce3667b3f69bf3ab3fd81c191aee51f8.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/ce3667b3f69bf3ab3fd81c191aee51f8.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<ol start="2">
<li>填写你的 Zwift 邮箱和密码，勾选所有选项，点击 Submit 提交</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/9cc77352a1f299516e1f76989bdc60c3.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/9cc77352a1f299516e1f76989bdc60c3.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<ol start="3">
<li>配置完成后，再次登录 Zwift 时就会显示为原来的账号了</li>
</ol>
<h3 id="32-配置-strava-自动上传">3.2 配置 Strava 自动上传</h3>
<h4 id="321-申请-strava-api">3.2.1 申请 Strava API</h4>
<ol>
<li>登录<a href="https://www.strava.com/settings/api">Strava API 设置页面</a></li>
<li>创建新应用，填写以下信息：
<ul>
<li><strong>应用名称</strong>：自定义（如：ZwiftOffline）</li>
<li><strong>类别</strong>：其他</li>
<li><strong>授权回调域</strong>：<code>launcher.zwift.com</code></li>
<li><strong>网站</strong>：可留空或填写个人网站</li>
</ul>
</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/d8024be9518e5a262538aa5d48c7fbb0.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/d8024be9518e5a262538aa5d48c7fbb0.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<ol start="3">
<li>申请完成后，记录下<code>Client ID</code>和<code>Client Secret</code></li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/a5024f9e2e150810251222315be11ac9.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/a5024f9e2e150810251222315be11ac9.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h4 id="322-在-zwiftoffline-中配置-strava">3.2.2 在 ZwiftOffline 中配置 Strava</h4>
<ol>
<li>在登录页面进入设置，填写<code>Client ID</code>和<code>Client Secret</code></li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/29afa480ea0c6ceba03f89a14b30c987.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/29afa480ea0c6ceba03f89a14b30c987.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/84b0932cd611d78a1497f82aafa86fb7.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/84b0932cd611d78a1497f82aafa86fb7.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>点击<code>Submit</code>提交：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/2457689c2493d63ffa77e465948d3d84.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/09/2457689c2493d63ffa77e465948d3d84.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h4 id="323-授权-strava-访问">3.2.3 授权 Strava 访问</h4>
<blockquote>
<p>这一步可以省略，如果通过上面的步骤没法上传，再尝试这个步骤手动配置</p>
</blockquote>
<ol>
<li>
<p>右键以管理员身份运行<code>zoffline-helper/disable_zoffline.bat</code>，清除 hosts 配置</p>
</li>
<li>
<p>在命令行中运行以下命令（替换<code>CLIENT_ID</code>和<code>CLIENT_SECRET</code>为你的实际值）：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">zoffline-helper/strava_auth.exe --client-id CLIENT_ID --client-secret CLIENT_SECRET
</span></span></code></pre></div></li>
<li>
<p>浏览器会自动打开或手动访问<code>localhost:8000</code>进行授权</p>
</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/05/18/4b0dbbd3bd2dd82b1c6da8327e494ea3.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/05/18/4b0dbbd3bd2dd82b1c6da8327e494ea3.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/05/18/05c02cfd9cd98aaf1e198d2f99b58f5a.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/05/18/05c02cfd9cd98aaf1e198d2f99b58f5a.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<ol start="4">
<li>授权完成后，将生成的<code>strava_token.txt</code>文件移动到<code>storage/1</code>目录下</li>
<li>右键以管理员身份运行<code>zoffline-helper/configure_client.bat</code>，重新配置 hosts</li>
</ol>
<h3 id="33-上传自定义训练课程">3.3 上传自定义训练课程</h3>
<p>如果你习惯在 Intervals ICU 等平台创建训练课程，可以手动上传到 Zwift 单机版。</p>
<p><strong>上传步骤：</strong></p>
<ol>
<li>
<p>将你的<code>.zwo</code>训练课程文件保存到以下目录：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Documents/Zwift/Workouts/1
</span></span></code></pre></div></li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/15/f18d29b2d3e548bf2fe0878d54b2f45f.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/15/f18d29b2d3e548bf2fe0878d54b2f45f.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<ol start="2">
<li><strong>⚠️ 注意</strong>：不是<code>zwiftoffline\storage\1\customworkouts</code>目录，如果放错位置会导致课程无法上传</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/15/edd5d0ab56c733e794d196838851dfe3.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/15/edd5d0ab56c733e794d196838851dfe3.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h3 id="34-配置-garmin-connect">3.4 配置 Garmin Connect</h3>
<p>Garmin Connect 可以同步你的 Zwift 活动数据到 Garmin 设备。</p>
<h4 id="341-配置账号">3.4.1 配置账号</h4>
<ol>
<li>
<p><strong>PC 端配置</strong></p>
<ul>
<li>在 ZwiftOffline 登录窗口点击&quot;Settings - Garmin&quot;按钮</li>
<li>输入你的 Garmin Connect 账号和密码</li>
</ul>
</li>
<li>
<p><strong>安卓端配置</strong></p>
<ul>
<li>访问 <code>https://&lt;zoffline_ip&gt;/garmin/zoffline/</code></li>
<li>输入你的 Garmin Connect 账号和密码</li>
<li>将<code>&lt;zoffline_ip&gt;</code>替换为运行 zoffline 的电脑 IP 地址</li>
</ul>
</li>
</ol>
<h4 id="342-多因素认证mfa">3.4.2 多因素认证（MFA）</h4>
<p>如果你的账号启用了多因素认证，需要额外配置：</p>
<ol>
<li>
<p><strong>使用 Python 脚本（推荐）</strong></p>
<ul>
<li>运行<code>garmin_auth.py</code>脚本</li>
<li>脚本会在运行目录下生成<code>garth</code>文件夹</li>
<li>将<code>garth</code>文件夹移动到<code>storage/1</code>目录下</li>
</ul>
</li>
<li>
<p><strong>使用 Windows 可执行文件</strong></p>
<ul>
<li>如果未安装 Python，可以从<a href="https://github.com/oldnapalm/zoffline-helper/releases/latest">zoffline-helper Release 页面</a>下载<code>garmin_auth.exe</code></li>
<li>运行<code>garmin_auth.exe</code>，同样会生成<code>garth</code>文件夹</li>
<li>将<code>garth</code>文件夹移动到<code>storage/1</code>目录下</li>
</ul>
</li>
</ol>
<h3 id="35-配置-intervalsicu">3.5 配置 Intervals.icu</h3>
<p>Intervals.icu 是一个强大的训练分析平台，可以同步 Zwift 活动数据。</p>
<h4 id="351-获取-api-凭证">3.5.1 获取 API 凭证</h4>
<ol>
<li>登录 <a href="https://intervals.icu/settings">Intervals.icu 设置页面</a></li>
<li>进入&quot;Developer Settings&quot;（开发者设置）部分</li>
<li>复制以下信息：
<ul>
<li><strong>Athlete ID</strong>（运动员 ID）</li>
<li><strong>API Key</strong>（API 密钥）</li>
</ul>
</li>
</ol>
<h4 id="352-配置账号">3.5.2 配置账号</h4>
<ol>
<li>
<p><strong>PC 端配置</strong></p>
<ul>
<li>在 ZwiftOffline 登录窗口点击&quot;Settings - Intervals&quot;按钮</li>
<li>输入之前复制的 Athlete ID 和 API Key</li>
</ul>
</li>
<li>
<p><strong>安卓端配置</strong></p>
<ul>
<li>访问 <code>https://&lt;zoffline_ip&gt;/intervals/zoffline/</code></li>
<li>输入 Athlete ID 和 API Key</li>
<li>将<code>&lt;zoffline_ip&gt;</code>替换为运行 zoffline 的电脑 IP 地址</li>
</ul>
</li>
</ol>
<h3 id="36-启用多人游戏">3.6 启用多人游戏</h3>
<p>多人游戏功能允许多个用户同时连接到同一个 zoffline 服务器进行骑行。</p>
<h4 id="361-基本配置">3.6.1 基本配置</h4>
<ol>
<li>在<code>storage</code>目录下创建<code>multiplayer.txt</code>文件（文件内容为空）</li>
</ol>
<h4 id="362-远程服务器配置">3.6.2 远程服务器配置</h4>
<p>如果 zoffline 运行在与 Zwift 客户端不同的 PC 上：</p>
<ol>
<li>在<code>storage</code>目录下创建<code>server-ip.txt</code>文件</li>
<li>文件内容填写运行 zoffline 的 PC 的 IP 地址</li>
<li><strong>端口要求</strong>：确保以下端口在运行 zoffline 的 PC 上开放：
<ul>
<li>TCP 端口：80, 443, 3025</li>
<li>UDP 端口：3024</li>
</ul>
</li>
</ol>
<h4 id="363-创建账号">3.6.3 创建账号</h4>
<ol>
<li>启动 Zwift，创建新账号</li>
<li><strong>⚠️ 注意</strong>：此账号仅存在于你的 zoffline 服务器上，与官方 Zwift 账号无关</li>
</ol>
<h4 id="364-启用密码重置功能可选">3.6.4 启用密码重置功能（可选）</h4>
<ol>
<li>在<code>storage</code>目录下创建<code>gmail_credentials.txt</code>文件</li>
<li>文件内容格式：</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">&lt;gmail 账号&gt;
</span></span><span class="line"><span class="cl">&lt;应用密码&gt;
</span></span><span class="line"><span class="cl">&lt;恢复 URL 主机（可选）&gt;
</span></span></code></pre></div><ol start="3">
<li><strong>获取应用密码</strong>：
<ul>
<li>访问 <a href="https://security.google.com/settings/security/apppasswords">https://security.google.com/settings/security/apppasswords</a></li>
<li>创建应用密码，允许服务器登录</li>
<li>将生成的应用密码填入文件第二行</li>
</ul>
</li>
<li><strong>恢复 URL 主机</strong>（可选）：
<ul>
<li>第三行可以填写恢复 URL 的主机地址</li>
<li>如果不填写，将使用服务器 IP 地址作为默认值</li>
</ul>
</li>
</ol>
<h3 id="37-启用-ghosts幽灵">3.7 启用 Ghosts（幽灵）</h3>
<p>Ghosts 功能可以保存你之前的骑行记录，并在相同路线上显示为&quot;幽灵&quot;与你一起骑行。</p>
<h4 id="371-启用功能">3.7.1 启用功能</h4>
<ol>
<li>
<p><strong>PC 端</strong></p>
<ul>
<li>在 zoffline 启动器窗口中勾选&quot;Enable ghosts&quot;</li>
</ul>
</li>
<li>
<p><strong>安卓端</strong></p>
<ul>
<li>访问 <code>https://&lt;zoffline_ip&gt;/user/zoffline/</code></li>
<li>勾选&quot;Enable ghosts&quot;</li>
<li>点击&quot;Start Zwift&quot;保存设置</li>
</ul>
</li>
</ol>
<h4 id="372-使用说明">3.7.2 使用说明</h4>
<ol>
<li><strong>保存幽灵</strong>：当你保存活动时，幽灵会自动保存在<code>storage/&lt;player_id&gt;/ghosts/&lt;world&gt;/&lt;route&gt;</code>目录下</li>
<li><strong>加载幽灵</strong>：下次骑行相同路线时，幽灵会自动加载</li>
<li><strong>重新编组</strong>：在聊天中输入<code>.regroup</code>命令可以重新编组幽灵</li>
</ol>
<h4 id="373-自定义装备">3.7.3 自定义装备</h4>
<ol>
<li>在<code>storage</code>目录下创建<code>ghost_profile.txt</code>文件</li>
<li>可以使用<code>find_equip.py</code>脚本来自动填充此文件</li>
</ol>
<h3 id="38-启用-bots机器人">3.8 启用 Bots（机器人）</h3>
<p>Bots 功能可以将保存的幽灵转换为持续骑行的机器人，无论你选择什么路线，它们都会继续骑行。</p>
<h4 id="381-启用功能">3.8.1 启用功能</h4>
<ol>
<li>在<code>storage</code>目录下创建<code>enable_bots.txt</code>文件</li>
<li><strong>可选</strong>：文件内容可以包含一个倍数（如：<code>2</code>表示双倍机器人数量）
<ul>
<li><strong>⚠️ 警告</strong>：如果机器人数量过多，可能导致性能问题或功能失效</li>
</ul>
</li>
</ol>
<h4 id="382-控制命令">3.8.2 控制命令</h4>
<p>在聊天中使用以下命令控制机器人：</p>
<ul>
<li><code>.group</code>：编组机器人</li>
<li><code>.groupall</code>：编组所有机器人（包括使用倍数时的重复机器人）</li>
<li><code>.autogroup</code>：自动编组（当你改变路线时）</li>
<li><code>.autogroupall</code>：自动编组所有机器人</li>
<li><code>.stopautogroup</code>：停止自动编组</li>
<li><code>.disperse</code>：随机化机器人位置</li>
</ul>
<h4 id="383-自定义机器人">3.8.3 自定义机器人</h4>
<ol>
<li>在<code>storage</code>目录下创建<code>bot.txt</code>文件</li>
<li>可以自定义机器人的名称、国籍和装备</li>
<li>可以使用<code>get_pro_names.py</code>脚本来自动填充此文件</li>
<li><strong>随机机器人</strong>：如果需要随机机器人，可以参考<a href="https://github.com/oldnapalm/zoffline-bots">zoffline-bots 仓库</a></li>
</ol>
<h3 id="39-配置-robopacers机器人配速员">3.9 配置 RoboPacers（机器人配速员）</h3>
<p>RoboPacers 是使用功率模拟器保存的幽灵，可以创建完美的循环配速员。</p>
<h4 id="391-获取-robopacers">3.9.1 获取 RoboPacers</h4>
<ol>
<li>可以从<a href="https://github.com/oldnapalm/zoffline-bots">zoffline-bots 仓库</a>下载预制的 RoboPacers</li>
</ol>
<h4 id="392-创建要求">3.9.2 创建要求</h4>
<p>要创建可用的 RoboPacer，需要满足以下条件：</p>
<ol>
<li><strong>更新频率</strong>：必须使用 1 秒的更新频率录制（默认是 3 秒）</li>
<li><strong>循环要求</strong>：活动必须从同一位置和速度开始和结束，否则机器人无法平滑循环</li>
<li><strong>配置文件要求</strong>：
<ul>
<li>必须包含唯一的玩家 ID</li>
<li>必须包含路线 ID</li>
<li>这样当你加入机器人时，会在交叉路口走相同的转弯</li>
</ul>
</li>
</ol>
<h4 id="393-编辑工具">3.9.3 编辑工具</h4>
<ol>
<li><strong>bot_editor.py 脚本</strong>：可以用于修改以下文件：
<ul>
<li><code>profile.bin</code>：设置名称、玩家 ID 和路线 ID</li>
<li><code>route.bin</code>：裁剪多余的点以创建完美循环</li>
</ul>
</li>
</ol>
<h4 id="394-创建动态-robopacer">3.9.4 创建动态 RoboPacer</h4>
<p>要创建动态 RoboPacer（在上坡时增加功率，下坡时减少功率）：</p>
<ol>
<li>使用 <a href="https://github.com/oldnapalm/zwift-offline/blob/master/standalone_power.py">standalone_power.py</a> 脚本</li>
<li><strong>硬件要求</strong>：
<ul>
<li>2 个 ANT 适配器</li>
<li><a href="https://github.com/mch/python-ant">python-ant</a></li>
<li><a href="https://github.com/oldnapalm/zwift-offline/blob/master/PowerMeterTx.py">PowerMeterTx.py</a></li>
</ul>
</li>
</ol>
<h3 id="310-使用-bookmarks书签">3.10 使用 Bookmarks（书签）</h3>
<p>书签功能可以保存你的位置，方便快速跳转到特定地点。</p>
<h4 id="3101-自动保存书签">3.10.1 自动保存书签</h4>
<p>当你完成活动时，你的最后位置会自动保存为书签。</p>
<h4 id="3102-手动保存书签">3.10.2 手动保存书签</h4>
<p>在聊天中使用以下命令保存书签：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">.bookmark &lt;名称&gt;
</span></span></code></pre></div><p>例如：<code>.bookmark 起点</code></p>
<h4 id="3103-使用书签">3.10.3 使用书签</h4>
<ol>
<li>
<p><strong>从书签开始新活动</strong>：</p>
<ul>
<li>在主页屏幕选择&quot;Join a Zwifter&quot;</li>
<li>选择你想要的书签</li>
</ul>
</li>
<li>
<p><strong>传送到书签</strong>：</p>
<ul>
<li>使用操作栏上的传送图标</li>
<li>选择目标书签进行传送</li>
</ul>
</li>
</ol>
<h3 id="311-启用历史排行榜">3.11 启用历史排行榜</h3>
<p>历史排行榜功能可以覆盖 60 分钟的实时结果和 90 天的个人记录，显示所有时间的最佳成绩。</p>
<h4 id="3111-启用功能">3.11.1 启用功能</h4>
<ol>
<li>在<code>storage</code>目录下创建<code>all_time_leaderboards.txt</code>文件（文件内容可以为空）</li>
</ol>
<h4 id="3112-功能说明">3.11.2 功能说明</h4>
<ul>
<li><strong>排行榜</strong>：显示所有时间的最佳成绩，而不仅仅是最近 60 分钟或 90 天的记录</li>
<li><strong>荣誉衫</strong>：仍然有效期为 60 分钟，但只有在创造新的历史记录时才会授予</li>
</ul>
<h3 id="312-解锁装备">3.12 解锁装备</h3>
<p>可以解锁特殊装备或所有装备。</p>
<h4 id="3121-解锁特殊装备">3.12.1 解锁特殊装备</h4>
<ol>
<li>在<code>storage</code>目录下创建<code>unlock_entitlements.txt</code>文件（文件内容可以为空）</li>
<li>这将解锁需要特殊权限的装备</li>
</ol>
<h4 id="3122-解锁所有装备">3.12.2 解锁所有装备</h4>
<ol>
<li>在<code>storage</code>目录下创建<code>unlock_all_equipment.txt</code>文件（文件内容可以为空）</li>
<li>这将解锁所有可用装备</li>
</ol>
<h3 id="313-配置-cdn-代理">3.13 配置 CDN 代理</h3>
<p>CDN 代理功能可以从 Zwift 官方服务器获取地图时间表和更新文件。</p>
<h4 id="3131-启用-cdn-代理">3.13.1 启用 CDN 代理</h4>
<ol>
<li>在<code>storage</code>目录下创建<code>cdn-proxy.txt</code>文件（文件内容可以为空）</li>
<li><strong>⚠️ 限制</strong>：此功能只能在 zoffline 运行在与 Zwift 客户端不同的机器上时使用</li>
</ol>
<h4 id="3132-禁用代理">3.13.2 禁用代理</h4>
<p>默认情况下，zoffline 会尝试使用 Google 公共 DNS 来解析 Zwift 主机名，即使 zoffline 与 Zwift 客户端运行在同一台机器上也能工作。</p>
<ol>
<li>如果要禁用此代理功能，在<code>storage</code>目录下创建<code>disable_proxy.txt</code>文件</li>
</ol>
<h4 id="3133-从-zoffline-提供更新文件">3.13.3 从 zoffline 提供更新文件</h4>
<ol>
<li>运行<code>get_gameassets.py</code>脚本下载游戏文件</li>
<li>这样 zoffline 可以直接提供更新文件，而不需要从 Zwift 服务器获取</li>
</ol>
<h2 id="四移动端-companion-配置">四、移动端 Companion 配置</h2>
<p>Zwift Companion 是配套的移动端社交软件，可用于与骑友互动、配对设备、点赞、使用道具等功能。使用离线版 Zwift 需要重新打包 Companion 应用。</p>
<h3 id="41-准备工作">4.1 准备工作</h3>
<p>官方原版 Companion 会对网络连接和证书做严格验证，需要对其进行&quot;打补丁并重签名&quot;才能连接到本地 zoffline 服务器。</p>
<h3 id="42-替换-apk-证书并重新签名">4.2 替换 APK 证书并重新签名</h3>
<h4 id="421-安装-apk-mitm">4.2.1 安装 apk-mitm</h4>
<ol>
<li>安装 Node.js（如果尚未安装）</li>
<li>使用以下命令全局安装 apk-mitm：</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm install -g apk-mitm
</span></span></code></pre></div><ol start="3">
<li>其他系统可参考<a href="https://github.com/shroudedcode/apk-mitm">apk-mitm 项目 README</a>自行安装</li>
</ol>
<h4 id="422-修改-apktool-配置">4.2.2 修改 apktool 配置</h4>
<ol>
<li>使用<code>npm root -g</code>查找 apk-mitm 的实际安装路径</li>
<li>打开<code>apk-mitm/dist/tools/apktool.js</code>文件</li>
<li>修改<code>decode</code>方法，添加<code>-resm</code>和<code>dummy</code>参数：</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl">    <span class="nx">decode</span><span class="p">(</span><span class="nx">inputPath</span><span class="p">,</span> <span class="nx">outputPath</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">run</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;decode&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;-resm&#39;</span><span class="p">,</span> <span class="c1">// add this
</span></span></span><span class="line"><span class="cl">            <span class="s1">&#39;dummy&#39;</span><span class="p">,</span> <span class="c1">// add this
</span></span></span><span class="line"><span class="cl">            <span class="nx">inputPath</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;--output&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">outputPath</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;--frame-path&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">frameworkPath</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span> <span class="s1">&#39;decoding&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span></code></pre></div><h4 id="423-生成修改后的-apk">4.2.3 生成修改后的 APK</h4>
<ol>
<li>
<p>从<a href="https://github.com/zoffline/zwift-offline">Zwift Offline 仓库</a>下载以下文件：</p>
<ul>
<li><code>ssl/cert-zwift-com.pem</code>（证书文件）</li>
<li><code>zwift-offline-companion.apk</code>（原始 APK 文件）</li>
</ul>
</li>
<li>
<p>将这两个文件复制到同一目录（如：<code>C:\Users\Administrator\Desktop\zwift-offline-companion</code>）</p>
</li>
<li>
<p>在该目录下运行以下命令：</p>
</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">apk-mitm --certificate cert-zwift-com.pem zwift-offline-companion.apk
</span></span></code></pre></div><ol start="4">
<li>命令执行完成后，会生成<code>zwift-offline-companion-patched.apk</code>文件，将其拷贝到手机安装即可</li>
</ol>
<h3 id="43-配置域名重定向">4.3 配置域名重定向</h3>
<h4 id="431-安装-virtual-hosts">4.3.1 安装 Virtual Hosts</h4>
<ol>
<li>下载<a href="https://github.com/x-falcon/Virtual-Hosts/releases/latest">virtual hosts</a>软件</li>
<li>安装到手机中</li>
</ol>
<h4 id="432-创建-hosts-文件">4.3.2 创建 hosts 文件</h4>
<ol>
<li>创建<code>hosts.txt</code>文件，内容如下（将<code>&lt;zoffline ip&gt;</code>替换为你运行 zoffline 的电脑 IP 地址）：</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">&lt;zoffline ip&gt; us-or-rly101.zwift.com
</span></span><span class="line"><span class="cl">&lt;zoffline ip&gt; secure.zwift.com
</span></span></code></pre></div><ol start="2">
<li><strong>⚠️ 重要提示</strong>：如果在 PC 上配置过 hosts 文件，可能包含以下映射：</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">127.0.0.1 cdn.zwift.com
</span></span></code></pre></div><p><strong>此映射不要添加到手机端的 hosts 文件中！</strong></p>
<ol start="3">
<li>将<code>hosts.txt</code>文件复制到手机，放在便于访问的位置</li>
</ol>
<h4 id="433-启用域名重定向">4.3.3 启用域名重定向</h4>
<ol>
<li>打开 Virtual Hosts 软件</li>
<li>选择之前创建的<code>hosts.txt</code>文件</li>
<li>启用域名重定向功能</li>
</ol>
<h3 id="44-使用-companion">4.4 使用 Companion</h3>
<ol>
<li>使用离线版的账号登录 Companion，即可正常使用</li>
<li><strong>验证连接</strong>：在打开和登录 Companion 时，观察 PC 端运行的 Zwift offline 命令行窗口是否有日志输出
<ul>
<li>如果有日志输出，说明连接正常</li>
<li>如果没有任何输出，说明请求未成功转发，需要检查 IP 地址配置是否正确</li>
</ul>
</li>
</ol>
<h2 id="五安卓设备直接使用-zwift-offline">五、安卓设备直接使用 Zwift Offline</h2>
<p>除了在 PC 上使用 Zwift Offline，你也可以直接在安卓设备上运行 Zwift 并连接到 zoffline 服务器。这种方式不需要 root 权限，但需要在每次安装或更新 Zwift 后重新打补丁。</p>
<h3 id="51-安装必要应用">5.1 安装必要应用</h3>
<h4 id="511-下载并安装-zofflineobb">5.1.1 下载并安装 ZofflineObb</h4>
<ol>
<li>从<a href="https://github.com/Argon2000/ZofflineObbAndroid/releases/latest">GitHub Release 页面</a>下载<code>ZofflineObb.apk</code></li>
<li>安装到安卓设备上（需要允许安装未知来源应用）</li>
</ol>
<h4 id="512-下载并安装-virtual-hosts">5.1.2 下载并安装 Virtual Hosts</h4>
<ol>
<li>从<a href="https://github.com/x-falcon/Virtual-Hosts/releases/latest">GitHub Release 页面</a>下载<code>app-Github-release.apk</code></li>
<li>安装到安卓设备上</li>
</ol>
<h3 id="52-配置域名重定向">5.2 配置域名重定向</h3>
<h4 id="521-创建-hoststxt-文件">5.2.1 创建 hosts.txt 文件</h4>
<ol>
<li>
<p>创建<code>hosts.txt</code>文件，可以使用文本编辑器应用或在线工具（如<a href="https://passwordsgenerator.net/text-editor/">在线文本编辑器</a>）</p>
</li>
<li>
<p>文件内容如下（将<code>&lt;zoffline ip&gt;</code>替换为运行 zoffline 的电脑 IP 地址）：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">&lt;zoffline ip&gt; us-or-rly101.zwift.com
</span></span><span class="line"><span class="cl">&lt;zoffline ip&gt; secure.zwift.com
</span></span><span class="line"><span class="cl">&lt;zoffline ip&gt; cdn.zwift.com
</span></span></code></pre></div><p><strong>⚠️ 注意</strong>：与 Companion 配置不同，安卓设备直接使用需要包含<code>cdn.zwift.com</code>的映射</p>
</li>
<li>
<p>将<code>hosts.txt</code>文件保存到手机，放在便于访问的位置</p>
</li>
</ol>
<h4 id="522-关闭-private-dns">5.2.2 关闭 Private DNS</h4>
<ol>
<li>进入安卓设备的<strong>设置</strong> &gt; <strong>网络和互联网</strong> &gt; <strong>高级</strong> &gt; <strong>Private DNS</strong></li>
<li>选择<strong>关闭</strong>或<strong>自动</strong></li>
</ol>
<h4 id="523-配置-virtual-hosts">5.2.3 配置 Virtual Hosts</h4>
<ol>
<li>打开 Virtual Hosts 应用</li>
<li>选择之前创建的<code>hosts.txt</code>文件</li>
<li>启用域名重定向功能（确保按钮处于开启状态）</li>
</ol>
<h4 id="524-替代方案使用-dns-配置">5.2.4 替代方案：使用 DNS 配置</h4>
<p>如果你不想使用 Virtual Hosts 应用，也可以使用以下方法：</p>
<ol>
<li>在运行 zoffline 的 PC 上，在<code>storage</code>目录下创建<code>fake-dns.txt</code>文件</li>
<li>在手机的 Wi-Fi 设置中，将<strong>DNS 1</strong>设置为运行 zoffline 的 PC 的 IP 地址</li>
<li><strong>注意</strong>：如果你的路由器支持，也可以在路由器层面配置 DNS 记录，这样所有设备都可以自动使用</li>
</ol>
<h3 id="53-安装并打补丁-zwift">5.3 安装并打补丁 Zwift</h3>
<h4 id="531-安装-zwift">5.3.1 安装 Zwift</h4>
<ol>
<li>从 Google Play 商店安装或更新 Zwift</li>
<li><strong>⚠️ 重要</strong>：安装或更新后，<strong>不要立即启动</strong> Zwift</li>
<li>如果已经启动过 Zwift，需要先清除数据：
<ul>
<li>进入<strong>设置</strong> &gt; <strong>应用</strong> &gt; <strong>Zwift</strong> &gt; <strong>存储</strong> &gt; <strong>清除数据</strong></li>
<li>或者卸载后重新安装</li>
</ul>
</li>
</ol>
<h4 id="532-运行-zofflineobb-打补丁">5.3.2 运行 ZofflineObb 打补丁</h4>
<ol>
<li>打开<code>ZofflineObb</code>应用</li>
<li>运行补丁程序（允许访问存储权限）</li>
<li>等待补丁过程完成（通常需要 5-10 分钟）</li>
<li>补丁完成后，应用会提示完成</li>
</ol>
<p><strong>原理说明</strong>：ZofflineObb 会修改 Zwift 应用，使其接受 zoffline 服务器的自签名证书，这是连接离线服务器的关键步骤。</p>
<h3 id="54-运行-zwift">5.4 运行 Zwift</h3>
<ol>
<li><strong>确保 Virtual Hosts 按钮处于开启状态</strong></li>
<li>启动 Zwift 应用</li>
<li>使用任意邮箱和密码登录，或创建新用户（如果启用了多人游戏功能）</li>
<li>Zwift 应该能够正常验证下载并运行</li>
</ol>
<h3 id="55-重要提示">5.5 重要提示</h3>
<ul>
<li><strong>每次更新后需要重新打补丁</strong>：无论是从 Google Play 更新 Zwift，还是重新安装，都需要重新运行 ZofflineObb 打补丁</li>
<li><strong>保持网络连接</strong>：确保安卓设备与运行 zoffline 的 PC 在同一局域网内</li>
<li><strong>防火墙设置</strong>：确保 PC 的防火墙允许 zoffline 的端口访问</li>
</ul>
<h2 id="六常见问题">六、常见问题</h2>
<h3 id="61-卡在蓝色登录界面">6.1 卡在蓝色登录界面</h3>
<p><strong>症状：</strong> 登录时卡在蓝色界面，无法进入游戏</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/20/03f08f3fa8d593d33b38647a46f22341.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/20/03f08f3fa8d593d33b38647a46f22341.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p><strong>解决方法：</strong></p>
<ol>
<li>在任务管理器中关闭 Zwift 进程</li>
<li>将输入法切换为<strong>微软英文输入法</strong></li>
<li>重新启动 Zwift 并登录</li>
</ol>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/20/48a6263e5ffe475ec5753b13cffd2ec1.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2025/02/20/48a6263e5ffe475ec5753b13cffd2ec1.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h3 id="62-配置后无法更新-zwift">6.2 配置后无法更新 Zwift</h3>
<p><strong>原因：</strong> <code>configure_client.bat</code>会修改 Hosts 文件，导致无法连接到 Zwift 服务器</p>
<p><strong>解决方法：</strong></p>
<ol>
<li>关闭正在运行的<code>zoffline</code></li>
<li>进入<code>zwiftoffline/zoffline-helper</code>目录</li>
<li>右键点击<code>disable_zoffline.bat</code>，选择<strong>以管理员身份运行</strong>，清除网络配置</li>
<li>打开 Zwift 进行更新</li>
<li>更新完成后，重新运行<code>configure_client.bat</code>恢复配置</li>
</ol>
<h3 id="63-无法自动上传活动到-strava">6.3 无法自动上传活动到 Strava</h3>
<p><strong>可能原因及解决方法：</strong></p>
<ol>
<li>检查<code>strava_token.txt</code>文件是否已正确放置在<code>storage/1</code>目录下</li>
<li>确认 Strava API 的<code>Client ID</code>和<code>Client Secret</code>配置正确</li>
<li>检查网络连接，确保 zoffline 可以访问 Strava API</li>
<li>查看 zoffline 命令行窗口的错误日志，根据具体错误信息进行排查</li>
<li>检查在申请 API 时填写的授权回调域是否正确</li>
</ol>
<h3 id="64-安卓客户端无法登录">6.4 安卓客户端无法登录</h3>
<p><strong>可能原因及解决方法：</strong></p>
<p><strong>对于 Companion 应用：</strong></p>
<ol>
<li>检查 Virtual Hosts 是否已正确启用</li>
<li>确认 hosts 文件中的 IP 地址是否正确（应为运行 zoffline 的电脑 IP，而非 127.0.0.1）</li>
<li>确保手机和电脑在同一局域网内</li>
<li>检查防火墙设置，确保 zoffline 的端口未被阻止</li>
<li>重新安装修改后的 APK 文件</li>
</ol>
<p><strong>对于直接使用 Zwift 应用：</strong></p>
<ol>
<li>确认已关闭 Private DNS 设置</li>
<li>检查 Virtual Hosts 是否已正确启用，按钮必须处于开启状态</li>
<li>确认 hosts.txt 文件包含所有三个域名映射（包括<code>cdn.zwift.com</code>）</li>
<li>检查是否在安装/更新 Zwift 后运行了 ZofflineObb 打补丁</li>
<li>如果已启动过 Zwift，尝试清除应用数据后重新打补丁</li>
<li>确认手机和运行 zoffline 的 PC 在同一局域网内</li>
<li>检查 PC 防火墙设置，确保 zoffline 端口未被阻止</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>速联SRAM RIVAL升级功率计</title>
      <link>https://lifeislife.cn/posts/%E9%80%9F%E8%81%94sram-rival%E5%8D%87%E7%BA%A7%E5%8A%9F%E7%8E%87%E8%AE%A1/</link>
      <pubDate>Sat, 02 Nov 2024 10:10:20 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E9%80%9F%E8%81%94sram-rival%E5%8D%87%E7%BA%A7%E5%8A%9F%E7%8E%87%E8%AE%A1/</guid>
      <description>&lt;h1 id=&#34;为什么要升级&#34;&gt;为什么要升级&lt;/h1&gt;
&lt;p&gt;人傻钱多（bushi）。平时骑台子能实时看到自己输出功率，判断自己的状态，也能更好的控制自己的训练强度，不至于过度训练。外出路骑没有功率计总觉得不得劲，特别是在蹭风或者团骑时，不知道自己的状态如何，因为路骑人比较兴奋，也许功率已经超过自己的FTP但是可能并不觉得累，但是体能是有限的，不累只是精神上的感觉，也许骑不了多久精神头过了就被拉爆了。所以十分想要一个功率计能够实时看到自己的输出功率，能让路骑尽量维持在自己想要的强度。&lt;/p&gt;
&lt;h1 id=&#34;前期准备&#34;&gt;前期准备&lt;/h1&gt;
&lt;p&gt;先了解和功率计相关的几个零件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;盘片
&lt;ul&gt;
&lt;li&gt;SRAM Rival 107BCD 盘片
&lt;ul&gt;
&lt;li&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/d8dbeaea4c456b12ab411f003817fa8e.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/d8dbeaea4c456b12ab411f003817fa8e.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;盘爪
&lt;ul&gt;
&lt;li&gt;SRAM Red AXS/Force
&lt;ul&gt;
&lt;li&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/731cdbc91ef46d8b83f288335e93d881.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/731cdbc91ef46d8b83f288335e93d881.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;盘钉：固定盘片和盘爪
&lt;ul&gt;
&lt;li&gt;SRAM RIVAL 107/94 BCD M8X4.75X8.75 盘钉
&lt;ul&gt;
&lt;li&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/36b8ba6a6ef7cf56fb28e6a5bfb7c497.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/36b8ba6a6ef7cf56fb28e6a5bfb7c497.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;曲柄
&lt;ul&gt;
&lt;li&gt;SRAM RIVAL AXS QUARQ DUB&lt;/li&gt;
&lt;li&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/27d80f442010abcb997944f0cbda099a.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/27d80f442010abcb997944f0cbda099a.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;曲柄螺丝
&lt;ul&gt;
&lt;li&gt;SRAM DUB AXS RED或FROCE 曲柄螺丝&lt;/li&gt;
&lt;li&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/ef2e8c647b649f55846b0df00219e73e.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/ef2e8c647b649f55846b0df00219e73e.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;中轴
&lt;ul&gt;
&lt;li&gt;和曲柄连接在一起&lt;/li&gt;
&lt;li&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/e4009029b373cefeb313f49b3b6953b3.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/e4009029b373cefeb313f49b3b6953b3.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;功率计的种类有很多，有脚踏功率计，盘爪功率计、曲柄功率计和贴片功率计等等，每种功率计都有自己的优缺点，因为我也不是专家所以就不详细介绍了，想要了解的可以参考视频&lt;a href=&#34;https://www.bilibili.com/video/BV1hj411s7mm/?spm_id_from=333.337.search-card.all.click&amp;amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44&#34;&gt;公路车功率计介绍和选择安装建议_哔哩哔哩_bilibili&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;我在看了一些介绍视频以及根据自己目前使用套件的情况，最终选择了使用人群最广的盘爪式功率计，盘爪功率计就是将上面提到的盘爪这个邻接用功率计替换，功率计本身就是盘爪。下面是我升级选购的一些思路，供和我一样的小白参考。&lt;/p&gt;
&lt;p&gt;当我决定使用盘爪式功率计时，就需要选择具体哪一款，哪一个品牌的功率计，可以直接淘宝搜索“盘爪功率计”，会有很多选择，如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;迈金 P505&lt;/li&gt;
&lt;li&gt;SRAM QUARQ&lt;/li&gt;
&lt;li&gt;Sigeyi 思各异&lt;/li&gt;
&lt;li&gt;XCADEY&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接下来就是根据自己的钱包大小来选择了，当然还有一个最重要的参数，就是BCD，这个参数是盘爪功率计的螺丝孔的间距，不同的品牌不同的型号的盘爪功率计BCD是不一样的，这个参数决定了功率计能否安装到牙盘上，我使用的是SRAM Rival eTap AXS套件，这个套件的BCD是107，所以我需要选择BCD为107的盘爪功率计。这时查看各个功率计详情可以看到迈金不支持107BCD，所以可以直接排除这款功率计了。在剩下的几款功率计中，SRAM QUARQ是SRAM自家的产品，我觉得原配最好，所以选择了SRAM QUARQ。&lt;/p&gt;
&lt;p&gt;关于盘片和盘爪规格的介绍可以参考视频&lt;a href=&#34;https://www.bilibili.com/video/BV1dM4m1y7c3/?spm_id_from=333.999.0.0&amp;amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44&#34;&gt;【自行车维修手册】第17期 公路车盘片选择与安装_哔哩哔哩_bilibili&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在确定了功率计后，就需要考虑如何安装了，RIVAL套件中，曲柄和盘爪是一体的，这意味着如果要在不更换盘片的情况下加装功率计，就需要更换曲柄。更换曲柄就需要了解曲柄的规格，有不同类型的中轴比如GXP和DU，有不同的曲柄长度，还有不同的安装规格，比如3钉，5钉，8钉等等。因为我们已经选好了盘爪功率计，而盘爪功率计是和曲柄安装在一起的，所以盘爪功率计的规格已经确定了曲柄的安装规格，比如QUARQ的盘爪功率计是8钉，所以我们需要选择8钉的曲柄。接下来就是选择曲柄的长度，曲柄的长度根据自己的身体数据来选择，没有Fitting的话就看原来曲柄的长度，换一个一样长度的即可，曲柄的长度标注在曲柄上，比如我的RIVAL套件是170mm。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/ad08bcbc03336c4db6c6fd64f55cec02.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/ad08bcbc03336c4db6c6fd64f55cec02.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/25f13723a0ef847e602331a4af015bd9.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/25f13723a0ef847e602331a4af015bd9.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;根据这些信息我选择了SRAM FORCE DUB 8 钉曲柄。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/1992762c24b909be05270aad2493df57.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/1992762c24b909be05270aad2493df57.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;关于曲柄规格的介绍可以参考视频&lt;a href=&#34;https://www.bilibili.com/video/BV1iW421R7se/?spm_id_from=333.999.0.0&amp;amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44&#34;&gt;【自行车维修手册】第15期 自行车曲柄牙盘规格区分介绍_哔哩哔哩_bilibili&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;至此主要的零件已经选购完毕，接下来就是等待零件到货，然后开始安装。但是安装少不了工具，需要准备的工具有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;8 mm 内六角扳手，拆卸安装曲柄&lt;/li&gt;
&lt;li&gt;空心钢管，用于拆卸安装曲柄，当做加力杆，曲柄的螺丝扭力高达50N.m，普通扳手力臂太小，很难拧下来&lt;/li&gt;
&lt;li&gt;6 mm 内六角扳手，拆卸安装脚踏&lt;/li&gt;
&lt;li&gt;2 mm 内六角扳手，调整曲柄锁紧环&lt;/li&gt;
&lt;li&gt;扭力扳手，安装曲柄螺丝&lt;/li&gt;
&lt;li&gt;界面脂&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;拆卸&#34;&gt;拆卸&lt;/h1&gt;
&lt;p&gt;曲柄拆卸方式可以参考视频&lt;a href=&#34;https://www.bilibili.com/video/BV13w4m1271e/?spm_id_from=333.337.search-card.all.click&amp;amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44&#34;&gt;技师手册十四（连载）速联RIVAL牙盘曲柄拆装_哔哩哔哩_bilibili&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/98c7b773a4f766c79beff19d2fd9a6fe.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/98c7b773a4f766c79beff19d2fd9a6fe.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;这里有个小技巧，就是在拆卸曲柄时，可以用一个空心钢管套在内六角扳手上，这样可以增加力臂，减小力臂，这样就可以更容易的拧下曲柄螺丝。还有如果你和我一样总记不住拆卸曲柄和脚踏的方向，那么可以这么记。&lt;strong&gt;拆卸的旋转方向都是踩踏前进的相反方向&lt;/strong&gt;。&lt;/p&gt;
&lt;h1 id=&#34;安装&#34;&gt;安装&lt;/h1&gt;
&lt;p&gt;安装就是把螺丝拧上，但是有一些细节需要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;曲柄和盘爪连接的螺丝的扭力值为 4 N.m&lt;/li&gt;
&lt;li&gt;大牙盘正面有一个金属圆柱，这个圆柱体需要在曲柄正下方
&lt;ul&gt;
&lt;li&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/8d795b69827bc54175e92387ff25e31e.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/8d795b69827bc54175e92387ff25e31e.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;li&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/86d9decd4c459c518c3bd83e284fcd6b.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/86d9decd4c459c518c3bd83e284fcd6b.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;小牙盘上有一个凸起的尖尖，这个尖尖需要在曲柄正下方
&lt;ul&gt;
&lt;li&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/047489de549a5d449be3d655314c06c2.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/047489de549a5d449be3d655314c06c2.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;小牙盘标注齿数和型号的那面正对自己才是正确的方向&lt;/li&gt;
&lt;li&gt;牙盘的盘钉扭力值为 10 N.m&lt;/li&gt;
&lt;li&gt;每个螺丝都抹上界面脂，因为牙盘上的螺丝都会受到很大的力，所以需要抹上界面脂，这样可以减小螺丝的摩擦力，减小螺丝的磨损，也可以防止异响&lt;/li&gt;
&lt;li&gt;中轴的大螺丝抹上黄油，扭力值至少为50 N.m，扭紧时最好用上空心钢管&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;参考资料&#34;&gt;参考资料&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1iW421R7se/?spm_id_from=333.999.0.0&amp;amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44&#34;&gt;【自行车维修手册】第15期 自行车曲柄牙盘规格区分介绍_哔哩哔哩_bilibili&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1dM4m1y7c3/?spm_id_from=333.999.0.0&amp;amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44&#34;&gt;【自行车维修手册】第17期 公路车盘片选择与安装_哔哩哔哩_bilibili&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1hj411s7mm/?spm_id_from=333.337.search-card.all.click&amp;amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44&#34;&gt;公路车功率计介绍和选择安装建议_哔哩哔哩_bilibili&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
      <content:encoded><![CDATA[<h1 id="为什么要升级">为什么要升级</h1>
<p>人傻钱多（bushi）。平时骑台子能实时看到自己输出功率，判断自己的状态，也能更好的控制自己的训练强度，不至于过度训练。外出路骑没有功率计总觉得不得劲，特别是在蹭风或者团骑时，不知道自己的状态如何，因为路骑人比较兴奋，也许功率已经超过自己的FTP但是可能并不觉得累，但是体能是有限的，不累只是精神上的感觉，也许骑不了多久精神头过了就被拉爆了。所以十分想要一个功率计能够实时看到自己的输出功率，能让路骑尽量维持在自己想要的强度。</p>
<h1 id="前期准备">前期准备</h1>
<p>先了解和功率计相关的几个零件：</p>
<ul>
<li>盘片
<ul>
<li>SRAM Rival 107BCD 盘片
<ul>
<li>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/d8dbeaea4c456b12ab411f003817fa8e.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/d8dbeaea4c456b12ab411f003817fa8e.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
</ul>
</li>
</ul>
</li>
<li>盘爪
<ul>
<li>SRAM Red AXS/Force
<ul>
<li>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/731cdbc91ef46d8b83f288335e93d881.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/731cdbc91ef46d8b83f288335e93d881.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
</ul>
</li>
</ul>
</li>
<li>盘钉：固定盘片和盘爪
<ul>
<li>SRAM RIVAL 107/94 BCD M8X4.75X8.75 盘钉
<ul>
<li>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/36b8ba6a6ef7cf56fb28e6a5bfb7c497.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/36b8ba6a6ef7cf56fb28e6a5bfb7c497.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
</ul>
</li>
</ul>
</li>
<li>曲柄
<ul>
<li>SRAM RIVAL AXS QUARQ DUB</li>
<li>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/27d80f442010abcb997944f0cbda099a.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/27d80f442010abcb997944f0cbda099a.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
</ul>
</li>
<li>曲柄螺丝
<ul>
<li>SRAM DUB AXS RED或FROCE 曲柄螺丝</li>
<li>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/ef2e8c647b649f55846b0df00219e73e.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/ef2e8c647b649f55846b0df00219e73e.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
</ul>
</li>
<li>中轴
<ul>
<li>和曲柄连接在一起</li>
<li>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/e4009029b373cefeb313f49b3b6953b3.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/02/e4009029b373cefeb313f49b3b6953b3.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
</ul>
</li>
</ul>
<p>功率计的种类有很多，有脚踏功率计，盘爪功率计、曲柄功率计和贴片功率计等等，每种功率计都有自己的优缺点，因为我也不是专家所以就不详细介绍了，想要了解的可以参考视频<a href="https://www.bilibili.com/video/BV1hj411s7mm/?spm_id_from=333.337.search-card.all.click&amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44">公路车功率计介绍和选择安装建议_哔哩哔哩_bilibili</a>。</p>
<p>我在看了一些介绍视频以及根据自己目前使用套件的情况，最终选择了使用人群最广的盘爪式功率计，盘爪功率计就是将上面提到的盘爪这个邻接用功率计替换，功率计本身就是盘爪。下面是我升级选购的一些思路，供和我一样的小白参考。</p>
<p>当我决定使用盘爪式功率计时，就需要选择具体哪一款，哪一个品牌的功率计，可以直接淘宝搜索“盘爪功率计”，会有很多选择，如：</p>
<ul>
<li>迈金 P505</li>
<li>SRAM QUARQ</li>
<li>Sigeyi 思各异</li>
<li>XCADEY</li>
</ul>
<p>接下来就是根据自己的钱包大小来选择了，当然还有一个最重要的参数，就是BCD，这个参数是盘爪功率计的螺丝孔的间距，不同的品牌不同的型号的盘爪功率计BCD是不一样的，这个参数决定了功率计能否安装到牙盘上，我使用的是SRAM Rival eTap AXS套件，这个套件的BCD是107，所以我需要选择BCD为107的盘爪功率计。这时查看各个功率计详情可以看到迈金不支持107BCD，所以可以直接排除这款功率计了。在剩下的几款功率计中，SRAM QUARQ是SRAM自家的产品，我觉得原配最好，所以选择了SRAM QUARQ。</p>
<p>关于盘片和盘爪规格的介绍可以参考视频<a href="https://www.bilibili.com/video/BV1dM4m1y7c3/?spm_id_from=333.999.0.0&amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44">【自行车维修手册】第17期 公路车盘片选择与安装_哔哩哔哩_bilibili</a></p>
<p>在确定了功率计后，就需要考虑如何安装了，RIVAL套件中，曲柄和盘爪是一体的，这意味着如果要在不更换盘片的情况下加装功率计，就需要更换曲柄。更换曲柄就需要了解曲柄的规格，有不同类型的中轴比如GXP和DU，有不同的曲柄长度，还有不同的安装规格，比如3钉，5钉，8钉等等。因为我们已经选好了盘爪功率计，而盘爪功率计是和曲柄安装在一起的，所以盘爪功率计的规格已经确定了曲柄的安装规格，比如QUARQ的盘爪功率计是8钉，所以我们需要选择8钉的曲柄。接下来就是选择曲柄的长度，曲柄的长度根据自己的身体数据来选择，没有Fitting的话就看原来曲柄的长度，换一个一样长度的即可，曲柄的长度标注在曲柄上，比如我的RIVAL套件是170mm。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/ad08bcbc03336c4db6c6fd64f55cec02.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/ad08bcbc03336c4db6c6fd64f55cec02.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/25f13723a0ef847e602331a4af015bd9.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/25f13723a0ef847e602331a4af015bd9.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>根据这些信息我选择了SRAM FORCE DUB 8 钉曲柄。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/1992762c24b909be05270aad2493df57.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/1992762c24b909be05270aad2493df57.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>关于曲柄规格的介绍可以参考视频<a href="https://www.bilibili.com/video/BV1iW421R7se/?spm_id_from=333.999.0.0&amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44">【自行车维修手册】第15期 自行车曲柄牙盘规格区分介绍_哔哩哔哩_bilibili</a></p>
<p>至此主要的零件已经选购完毕，接下来就是等待零件到货，然后开始安装。但是安装少不了工具，需要准备的工具有：</p>
<ul>
<li>8 mm 内六角扳手，拆卸安装曲柄</li>
<li>空心钢管，用于拆卸安装曲柄，当做加力杆，曲柄的螺丝扭力高达50N.m，普通扳手力臂太小，很难拧下来</li>
<li>6 mm 内六角扳手，拆卸安装脚踏</li>
<li>2 mm 内六角扳手，调整曲柄锁紧环</li>
<li>扭力扳手，安装曲柄螺丝</li>
<li>界面脂</li>
</ul>
<h1 id="拆卸">拆卸</h1>
<p>曲柄拆卸方式可以参考视频<a href="https://www.bilibili.com/video/BV13w4m1271e/?spm_id_from=333.337.search-card.all.click&amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44">技师手册十四（连载）速联RIVAL牙盘曲柄拆装_哔哩哔哩_bilibili</a>。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/98c7b773a4f766c79beff19d2fd9a6fe.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/05/98c7b773a4f766c79beff19d2fd9a6fe.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>这里有个小技巧，就是在拆卸曲柄时，可以用一个空心钢管套在内六角扳手上，这样可以增加力臂，减小力臂，这样就可以更容易的拧下曲柄螺丝。还有如果你和我一样总记不住拆卸曲柄和脚踏的方向，那么可以这么记。<strong>拆卸的旋转方向都是踩踏前进的相反方向</strong>。</p>
<h1 id="安装">安装</h1>
<p>安装就是把螺丝拧上，但是有一些细节需要注意：</p>
<ul>
<li>曲柄和盘爪连接的螺丝的扭力值为 4 N.m</li>
<li>大牙盘正面有一个金属圆柱，这个圆柱体需要在曲柄正下方
<ul>
<li>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/8d795b69827bc54175e92387ff25e31e.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/8d795b69827bc54175e92387ff25e31e.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
<li>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/86d9decd4c459c518c3bd83e284fcd6b.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/86d9decd4c459c518c3bd83e284fcd6b.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
</ul>
</li>
<li>小牙盘上有一个凸起的尖尖，这个尖尖需要在曲柄正下方
<ul>
<li>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/047489de549a5d449be3d655314c06c2.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/11/06/047489de549a5d449be3d655314c06c2.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
</ul>
</li>
<li>小牙盘标注齿数和型号的那面正对自己才是正确的方向</li>
<li>牙盘的盘钉扭力值为 10 N.m</li>
<li>每个螺丝都抹上界面脂，因为牙盘上的螺丝都会受到很大的力，所以需要抹上界面脂，这样可以减小螺丝的摩擦力，减小螺丝的磨损，也可以防止异响</li>
<li>中轴的大螺丝抹上黄油，扭力值至少为50 N.m，扭紧时最好用上空心钢管</li>
</ul>
<h1 id="参考资料">参考资料</h1>
<ul>
<li><a href="https://www.bilibili.com/video/BV1iW421R7se/?spm_id_from=333.999.0.0&amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44">【自行车维修手册】第15期 自行车曲柄牙盘规格区分介绍_哔哩哔哩_bilibili</a></li>
<li><a href="https://www.bilibili.com/video/BV1dM4m1y7c3/?spm_id_from=333.999.0.0&amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44">【自行车维修手册】第17期 公路车盘片选择与安装_哔哩哔哩_bilibili</a></li>
<li><a href="https://www.bilibili.com/video/BV1hj411s7mm/?spm_id_from=333.337.search-card.all.click&amp;vd_source=7ff88341de4b5111bdf3db48b4e9ca44">公路车功率计介绍和选择安装建议_哔哩哔哩_bilibili</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>GearAutomator生成Strava运动热图和天气卡片</title>
      <link>https://lifeislife.cn/posts/gearautomator%E7%94%9F%E6%88%90strava%E8%BF%90%E5%8A%A8%E7%83%AD%E5%9B%BE%E5%92%8C%E5%A4%A9%E6%B0%94%E5%8D%A1%E7%89%87/</link>
      <pubDate>Sat, 24 Aug 2024 13:10:20 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/gearautomator%E7%94%9F%E6%88%90strava%E8%BF%90%E5%8A%A8%E7%83%AD%E5%9B%BE%E5%92%8C%E5%A4%A9%E6%B0%94%E5%8D%A1%E7%89%87/</guid>
      <description>&lt;h1 id=&#34;同步-strava-数据&#34;&gt;同步 Strava 数据&lt;/h1&gt;
&lt;p&gt;GearAutomator 是一个可以生成 Strava 运动热图和天气卡片的工具，访问 &lt;a href=&#34;https://www.gearaut.com&#34;&gt;GearAutomator&lt;/a&gt;，点击的&lt;code&gt;Connect with Strava&lt;/code&gt;按钮，然后输入 Strava 的用户名和密码登录。&lt;/p&gt;
&lt;p&gt;根据运动数据量不同，生成时间会有所不同，请勿关闭页面，等待生成完成。Strava的API限制很严格，同步数据很慢，连接上Strava之后，建议干其他事情，等待数据同步完成，不用频繁刷新页面。我第一次同步数据不知道花了多久一直没有显示热图，以为这个工具失效了，后来某一天再次访问，发现热图已经生成了。&lt;/p&gt;
&lt;h1 id=&#34;查看热图&#34;&gt;查看热图&lt;/h1&gt;
&lt;p&gt;Zwift虚拟骑行也会使用真实的GPX数据，所以在热力地图中也能看到有轨迹，虚拟骑行会用紫色轨迹表示，真实骑行会用绿色轨迹表示。图中紫色轨迹就是巴黎香街冲刺。绿色轨迹是一次路骑。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/fed51344e1e22419ca0ef77be2175cd5.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/fed51344e1e22419ca0ef77be2175cd5.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/a4ec56ea0604b336d80ff0fe8369dd2c.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/a4ec56ea0604b336d80ff0fe8369dd2c.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h1 id=&#34;配置天气卡片&#34;&gt;配置天气卡片&lt;/h1&gt;
&lt;p&gt;Strava 订阅用户可以生成每次运动的天气卡片，可以在运动简介中看到这次运动时的天气情况，如图所示：&lt;/p&gt;
&lt;p&gt;没有订阅的用户也可以通过这个工具来生成，在天气配置页面，开启即可：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/b9732209d84fd4164a684bb7a66eaab6.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/b9732209d84fd4164a684bb7a66eaab6.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;当下次有新的数据同步到Strava时，会自动在标题下面生成天气信息，如图所示：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/1d2987ccad88c1736c7251b0bb35d299.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/1d2987ccad88c1736c7251b0bb35d299.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;如果你想自定义天气卡片的样式，可以在天气卡片配置页面进行设置，比如将英文转换为中文：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/42dc1ed8021b3f224c2e7c61513ca19b.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/42dc1ed8021b3f224c2e7c61513ca19b.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;你可以直接复制下面的文本，替换即可：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;温度&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${temperature}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;体感温度&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${apparentTemperature}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;天气状况&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${skyCon}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;湿度&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${humidity}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;气压&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${pressure}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;云量&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${cloudRate}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;风速&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${windSpeed}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;能见度&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${visibility}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;空气质量&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;空气质量指数(AQI)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${aqi}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;细颗粒物(PM2.5)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${pm25}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;可吸入颗粒物(PM10)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${pm10}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;臭氧(O3)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${o3}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;二氧化硫(SO2)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${so2}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;二氧化氮(NO2)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${no2}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;一氧化碳(CO)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${co}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;紫外线强度(UV)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${uv}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;地面接收的太阳辐射(DSWRF)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${dswrf}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;温度&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startTemperature} - ${endTemperature}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;体感温度&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startApparentTemperature} - ${endApparentTemperature}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;天气状况&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startSkyCon} - ${endSkyCon}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;湿度&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startHumidity} - ${endHumidity}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;气压&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startPressure} - ${endPressure}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;云量&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startCloudRate} - ${endCloudRate}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;风速&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startWindSpeed} - ${endWindSpeed}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;能见度&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startVisibility} - ${endVisibility}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;空气质量&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;空气质量指数(AQI)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startAqi} - ${endAqi}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;细颗粒物(PM2.5)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startPM25} - ${endPM25}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;可吸入颗粒物(PM10)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startPM10} - ${endPM10}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;臭氧(O3)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startO3} - ${endO3}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;二氧化硫(SO2)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startSO2} - ${endSO2}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;二氧化氮(NO2)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startNO2} - ${endNO2}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;一氧化碳(CO)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startCO} - ${endCO}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;紫外线强度(UV)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startUV} - ${endUV}  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;地面接收的太阳辐射(DSWRF)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${startDswrf} - ${endDswrf}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <content:encoded><![CDATA[<h1 id="同步-strava-数据">同步 Strava 数据</h1>
<p>GearAutomator 是一个可以生成 Strava 运动热图和天气卡片的工具，访问 <a href="https://www.gearaut.com">GearAutomator</a>，点击的<code>Connect with Strava</code>按钮，然后输入 Strava 的用户名和密码登录。</p>
<p>根据运动数据量不同，生成时间会有所不同，请勿关闭页面，等待生成完成。Strava的API限制很严格，同步数据很慢，连接上Strava之后，建议干其他事情，等待数据同步完成，不用频繁刷新页面。我第一次同步数据不知道花了多久一直没有显示热图，以为这个工具失效了，后来某一天再次访问，发现热图已经生成了。</p>
<h1 id="查看热图">查看热图</h1>
<p>Zwift虚拟骑行也会使用真实的GPX数据，所以在热力地图中也能看到有轨迹，虚拟骑行会用紫色轨迹表示，真实骑行会用绿色轨迹表示。图中紫色轨迹就是巴黎香街冲刺。绿色轨迹是一次路骑。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/fed51344e1e22419ca0ef77be2175cd5.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/fed51344e1e22419ca0ef77be2175cd5.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/a4ec56ea0604b336d80ff0fe8369dd2c.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/a4ec56ea0604b336d80ff0fe8369dd2c.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h1 id="配置天气卡片">配置天气卡片</h1>
<p>Strava 订阅用户可以生成每次运动的天气卡片，可以在运动简介中看到这次运动时的天气情况，如图所示：</p>
<p>没有订阅的用户也可以通过这个工具来生成，在天气配置页面，开启即可：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/b9732209d84fd4164a684bb7a66eaab6.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/b9732209d84fd4164a684bb7a66eaab6.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>当下次有新的数据同步到Strava时，会自动在标题下面生成天气信息，如图所示：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/1d2987ccad88c1736c7251b0bb35d299.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/1d2987ccad88c1736c7251b0bb35d299.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>如果你想自定义天气卡片的样式，可以在天气卡片配置页面进行设置，比如将英文转换为中文：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/42dc1ed8021b3f224c2e7c61513ca19b.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/24/42dc1ed8021b3f224c2e7c61513ca19b.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>你可以直接复制下面的文本，替换即可：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">温度</span><span class="p">:</span><span class="w"> </span><span class="l">${temperature}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">体感温度</span><span class="p">:</span><span class="w"> </span><span class="l">${apparentTemperature}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">天气状况</span><span class="p">:</span><span class="w"> </span><span class="l">${skyCon}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">湿度</span><span class="p">:</span><span class="w"> </span><span class="l">${humidity}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">气压</span><span class="p">:</span><span class="w"> </span><span class="l">${pressure}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">云量</span><span class="p">:</span><span class="w"> </span><span class="l">${cloudRate}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">风速</span><span class="p">:</span><span class="w"> </span><span class="l">${windSpeed}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">能见度</span><span class="p">:</span><span class="w"> </span><span class="l">${visibility}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">空气质量</span><span class="p">:</span><span class="w">  
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">空气质量指数(AQI)</span><span class="p">:</span><span class="w"> </span><span class="l">${aqi}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">细颗粒物(PM2.5)</span><span class="p">:</span><span class="w"> </span><span class="l">${pm25}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">可吸入颗粒物(PM10)</span><span class="p">:</span><span class="w"> </span><span class="l">${pm10}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">臭氧(O3)</span><span class="p">:</span><span class="w"> </span><span class="l">${o3}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">二氧化硫(SO2)</span><span class="p">:</span><span class="w"> </span><span class="l">${so2}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">二氧化氮(NO2)</span><span class="p">:</span><span class="w"> </span><span class="l">${no2}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">一氧化碳(CO)</span><span class="p">:</span><span class="w"> </span><span class="l">${co}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">紫外线强度(UV)</span><span class="p">:</span><span class="w"> </span><span class="l">${uv}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">地面接收的太阳辐射(DSWRF)</span><span class="p">:</span><span class="w"> </span><span class="l">${dswrf}</span><span class="w">
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">温度</span><span class="p">:</span><span class="w"> </span><span class="l">${startTemperature} - ${endTemperature}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">体感温度</span><span class="p">:</span><span class="w"> </span><span class="l">${startApparentTemperature} - ${endApparentTemperature}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">天气状况</span><span class="p">:</span><span class="w"> </span><span class="l">${startSkyCon} - ${endSkyCon}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">湿度</span><span class="p">:</span><span class="w"> </span><span class="l">${startHumidity} - ${endHumidity}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">气压</span><span class="p">:</span><span class="w"> </span><span class="l">${startPressure} - ${endPressure}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">云量</span><span class="p">:</span><span class="w"> </span><span class="l">${startCloudRate} - ${endCloudRate}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">风速</span><span class="p">:</span><span class="w"> </span><span class="l">${startWindSpeed} - ${endWindSpeed}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">能见度</span><span class="p">:</span><span class="w"> </span><span class="l">${startVisibility} - ${endVisibility}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">空气质量</span><span class="p">:</span><span class="w">  
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">空气质量指数(AQI)</span><span class="p">:</span><span class="w"> </span><span class="l">${startAqi} - ${endAqi}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">细颗粒物(PM2.5)</span><span class="p">:</span><span class="w"> </span><span class="l">${startPM25} - ${endPM25}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">可吸入颗粒物(PM10)</span><span class="p">:</span><span class="w"> </span><span class="l">${startPM10} - ${endPM10}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">臭氧(O3)</span><span class="p">:</span><span class="w"> </span><span class="l">${startO3} - ${endO3}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">二氧化硫(SO2)</span><span class="p">:</span><span class="w"> </span><span class="l">${startSO2} - ${endSO2}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">二氧化氮(NO2)</span><span class="p">:</span><span class="w"> </span><span class="l">${startNO2} - ${endNO2}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">一氧化碳(CO)</span><span class="p">:</span><span class="w"> </span><span class="l">${startCO} - ${endCO}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">紫外线强度(UV)</span><span class="p">:</span><span class="w"> </span><span class="l">${startUV} - ${endUV}  </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">地面接收的太阳辐射(DSWRF)</span><span class="p">:</span><span class="w"> </span><span class="l">${startDswrf} - ${endDswrf}</span><span class="w">
</span></span></span></code></pre></div>]]></content:encoded>
    </item>
    <item>
      <title>Elevate for Strava浏览器插件更全面的骑行数据分析</title>
      <link>https://lifeislife.cn/posts/elevate-for-strava%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8F%92%E4%BB%B6%E6%9B%B4%E5%85%A8%E9%9D%A2%E7%9A%84%E9%AA%91%E8%A1%8C%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/</link>
      <pubDate>Sun, 11 Aug 2024 20:00:13 +0800</pubDate>
      <guid>https://lifeislife.cn/posts/elevate-for-strava%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8F%92%E4%BB%B6%E6%9B%B4%E5%85%A8%E9%9D%A2%E7%9A%84%E9%AA%91%E8%A1%8C%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/</guid>
      <description>&lt;p&gt;推荐一个开源工具，&lt;a href=&#34;https://github.com/thomaschampagne/elevate&#34;&gt;Elevate for Strava&lt;/a&gt;，可以为 Strava 提供丰富的数据分析功能，帮助骑行爱好者和运动员更好地了解自己的运动表现。目前有Web插件、Windows APP和MacOS APP。开发者表示未来主要是提供应用软件，插件开发可能投入会减少，如果想要更快更全面体验软件功能，推荐使用Windows APP或MacOS APP。因为Web插件使用更加方便，所以我就以Web插件为例进行介绍。&lt;/p&gt;
&lt;h2 id=&#34;安装工具&#34;&gt;安装工具&lt;/h2&gt;
&lt;p&gt;以下是简单的安装步骤，App版本可以前往&lt;a href=&#34;https://github.com/thomaschampagne/elevate&#34;&gt;Elevate for Strava&lt;/a&gt;的github主页Release页面下载。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安装扩展程序&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户可以通过 Chrome 或 Firefox 浏览器的扩展商店搜索“Elevate for Strava”，然后点击“安装”按钮。如果你是Chrome用户，可以点击&lt;a href=&#34;https://chromewebstore.google.com/detail/elevate-for-strava/dhiaggccakkgdfcadnklkbljcgicpckn&#34;&gt;此链接&lt;/a&gt;直达。其他浏览器可以&lt;a href=&#34;https://thomaschampagne.github.io/elevate/#/landing&#34;&gt;访问官网查看&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;同步 Strava 数据&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安装完成后，用户需要登录他们的 Strava 账户，并授权 Elevate 访问其运动数据。之后，Elevate 将自动同步 Strava 数据，并开始生成各种分析报告。


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/a7e7fcb06615b3c2f248176404c6a657.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/a7e7fcb06615b3c2f248176404c6a657.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配置和使用&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户可以根据自己的需求调整 Elevate 的设置，包括单位、分析参数等选项。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;使用介绍&#34;&gt;使用介绍&lt;/h2&gt;
&lt;p&gt;第一次导入成功后先别着急查看数据，先配置一下个人信息，参考下图。切记基本信息和Strava保持一致，不然重新导入真的很费时间，因为Strava接口请求有限制，你可以在Strava申请导出所有数据为文件，这样会快很多，后面再详细介绍。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/277c631d2d6ccfd6f773c597acfd2f22.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/277c631d2d6ccfd6f773c597acfd2f22.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;查看活动汇总&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/c02f376a56f92c647d3568ce55a790ca.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/c02f376a56f92c647d3568ce55a790ca.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;设置年度目标，计算目标进度&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/6d40e1a8a47cc775db4017d2dbaf6ad6.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/6d40e1a8a47cc775db4017d2dbaf6ad6.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/1619fb87264a40ff328bbcee8a1a5ae5.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/1619fb87264a40ff328bbcee8a1a5ae5.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;你是不是也想知道自己关注的大佬功率是多少？嘿嘿，Elevate会根据大佬公开的数据，预估一个功率和工体比。以下就是范二特的一次骑行数据。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/12/6fffdb98932e9b8b1a39c9aeb08da701.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/12/6fffdb98932e9b8b1a39c9aeb08da701.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;More Data！点击橙色的按钮，可以显示更多的数据信息，当然这些信息对于普通骑行者作用不大。对于业余车手可以通过这些数据来学习一下职业车手的骑行习惯。比如功率分配，踏频分配等等。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/12/f0259d2d859d146985934a3c86815920.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/12/f0259d2d859d146985934a3c86815920.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<p>推荐一个开源工具，<a href="https://github.com/thomaschampagne/elevate">Elevate for Strava</a>，可以为 Strava 提供丰富的数据分析功能，帮助骑行爱好者和运动员更好地了解自己的运动表现。目前有Web插件、Windows APP和MacOS APP。开发者表示未来主要是提供应用软件，插件开发可能投入会减少，如果想要更快更全面体验软件功能，推荐使用Windows APP或MacOS APP。因为Web插件使用更加方便，所以我就以Web插件为例进行介绍。</p>
<h2 id="安装工具">安装工具</h2>
<p>以下是简单的安装步骤，App版本可以前往<a href="https://github.com/thomaschampagne/elevate">Elevate for Strava</a>的github主页Release页面下载。</p>
<ol>
<li>
<p><strong>安装扩展程序</strong></p>
<ul>
<li>用户可以通过 Chrome 或 Firefox 浏览器的扩展商店搜索“Elevate for Strava”，然后点击“安装”按钮。如果你是Chrome用户，可以点击<a href="https://chromewebstore.google.com/detail/elevate-for-strava/dhiaggccakkgdfcadnklkbljcgicpckn">此链接</a>直达。其他浏览器可以<a href="https://thomaschampagne.github.io/elevate/#/landing">访问官网查看</a>。</li>
</ul>
</li>
<li>
<p><strong>同步 Strava 数据</strong></p>
<ul>
<li>安装完成后，用户需要登录他们的 Strava 账户，并授权 Elevate 访问其运动数据。之后，Elevate 将自动同步 Strava 数据，并开始生成各种分析报告。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/a7e7fcb06615b3c2f248176404c6a657.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/a7e7fcb06615b3c2f248176404c6a657.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></li>
</ul>
</li>
<li>
<p><strong>配置和使用</strong></p>
<ul>
<li>用户可以根据自己的需求调整 Elevate 的设置，包括单位、分析参数等选项。</li>
</ul>
</li>
</ol>
<h2 id="使用介绍">使用介绍</h2>
<p>第一次导入成功后先别着急查看数据，先配置一下个人信息，参考下图。切记基本信息和Strava保持一致，不然重新导入真的很费时间，因为Strava接口请求有限制，你可以在Strava申请导出所有数据为文件，这样会快很多，后面再详细介绍。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/277c631d2d6ccfd6f773c597acfd2f22.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/277c631d2d6ccfd6f773c597acfd2f22.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>查看活动汇总</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/c02f376a56f92c647d3568ce55a790ca.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/c02f376a56f92c647d3568ce55a790ca.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>设置年度目标，计算目标进度</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/6d40e1a8a47cc775db4017d2dbaf6ad6.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/6d40e1a8a47cc775db4017d2dbaf6ad6.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/1619fb87264a40ff328bbcee8a1a5ae5.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/11/1619fb87264a40ff328bbcee8a1a5ae5.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>你是不是也想知道自己关注的大佬功率是多少？嘿嘿，Elevate会根据大佬公开的数据，预估一个功率和工体比。以下就是范二特的一次骑行数据。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/12/6fffdb98932e9b8b1a39c9aeb08da701.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/12/6fffdb98932e9b8b1a39c9aeb08da701.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>More Data！点击橙色的按钮，可以显示更多的数据信息，当然这些信息对于普通骑行者作用不大。对于业余车手可以通过这些数据来学习一下职业车手的骑行习惯。比如功率分配，踏频分配等等。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/12/f0259d2d859d146985934a3c86815920.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/08/12/f0259d2d859d146985934a3c86815920.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
]]></content:encoded>
    </item>
    <item>
      <title>小白环法观赛指南</title>
      <link>https://lifeislife.cn/posts/%E5%B0%8F%E7%99%BD%E7%8E%AF%E6%B3%95%E8%A7%82%E8%B5%9B%E6%8C%87%E5%8D%97/</link>
      <pubDate>Tue, 02 Jul 2024 13:51:31 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E5%B0%8F%E7%99%BD%E7%8E%AF%E6%B3%95%E8%A7%82%E8%B5%9B%E6%8C%87%E5%8D%97/</guid>
      <description>&lt;h2 id=&#34;常见术语&#34;&gt;常见术语&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;黄衫（Yellow jersey/Maillot Jaune）
黄衫是总成绩领先者的象征，穿上黄衫的车手就是比赛的领头羊。&lt;/li&gt;
&lt;li&gt;绿衫（Green jersey/Maillot Vert）
绿衫代表冲刺积分的领先者，通常由擅长平地冲刺的车手穿着。&lt;/li&gt;
&lt;li&gt;圆点衫（Polka dot jersey/Maillot à Pois Rouges）
圆点衫授予爬坡积分最高的车手，爬坡能力强的车手更有机会获得。&lt;/li&gt;
&lt;li&gt;白衫（White jersey/Maillot Blanc）
白衫是最佳年轻车手（25岁以下）的象征，表现优异的年轻车手会穿上白衫。&lt;/li&gt;
&lt;li&gt;突围/兔子（Breakaway）
指比赛中一小部分车手从主集团（Peloton）中突围出来，尝试抢占领先位置。&lt;/li&gt;
&lt;li&gt;主集团（Peloton）
主集团是比赛中最大的车手队伍，大部分车手都会待在主集团里，节省体力。&lt;/li&gt;
&lt;li&gt;冲刺（Sprint）
冲刺是比赛最后几百米的激烈竞争，冲刺手（Sprinter）们会在这时全力以赴，争夺赛段冠军。&lt;/li&gt;
&lt;li&gt;掉队（Dropped）
被其他选手甩在后面，也被称为off the back或者out the back。&lt;/li&gt;
&lt;li&gt;计时赛（Time Trial）
计时赛是车手单独出发，按时间计成绩的比赛形式，包括个人计时赛（ITT）和团队计时赛（TTT）。&lt;/li&gt;
&lt;li&gt;总成绩（General Classification, GC）
总成绩是根据车手每个赛段的时间累加计算的，最终总时间最少的车手将获得黄衫。&lt;/li&gt;
&lt;li&gt;皇后赛段（Queen Stage）
指的是能够决定多日赛最终排名的关键性山地赛段，通常有数座难度很大的山峰。&lt;/li&gt;
&lt;li&gt;火车（Paceline）
指的是队友在前面做苦力，保护主将，为主将节省体力的战术。（对应的有冲刺火车或是山地火车）&lt;/li&gt;
&lt;li&gt;跟风/蹭风/吸尾流（Draft）
在高速骑行过程中，车手的大部分体力是消耗在对抗空气阻力（风阻）上。因此会有车手骑在其他人或车子后方，来降低风阻，节省体力。&lt;/li&gt;
&lt;li&gt;粘瓶（Sticky Bpttle）
选手在拿补给车的水壶时，会短暂获得补给车所带来的助力，以节省体力，通常三五秒之内都是被允许的，如果时间太长被裁判发现将会被罚款甚至取消成绩。&lt;/li&gt;
&lt;li&gt;关门时间（Time limit）
在每天的比赛中，车手们必须在不超过当日赛段冠军用时的一定比例时间内完赛，否则将被取消比赛资格，不被获准在第二天的比赛时发车；确切的比例取决于赛段的类型、地形和速度；速度快时，在平地赛段中，比例会低至5%，而速度慢时，在山地赛段中，比例会达到16、17%。在某些情况下，赛事组织者有权酌情赦免一些车手，比如当有过大一部分车手无法在关门时间内完赛时。历史上也有过特例，一些大牌冲刺手被关门，然后组委会以扣冲刺积分的形式来放他们一马。&lt;/li&gt;
&lt;li&gt;爬坡点等级（Mountain Climb Classification）
比赛中设置的爬坡抢分点，难度与级数由低至高为4、3、2、1、HC（顶级）；越高的级数代表爬坡长度越长、坡度越陡。&lt;/li&gt;
&lt;li&gt;补给区 Feed Zone
比赛中设置一个区域，让车队提供车手饮食补给袋的地方。通常，车手不会在这个区域发动攻击。&lt;/li&gt;
&lt;li&gt;垃圾丢弃区（Collection Zone）
UCI规定只能在固定的垃圾丢弃区扔垃圾，否则会被罚款。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;自行车战术&#34;&gt;自行车战术&lt;/h2&gt;
&lt;p&gt;油管上有个台湾博主叫做&lt;a href=&#34;https://www.youtube.com/watch?v=f1ncgvjB_z4&amp;amp;list=PLa5LB6K0vQT3CzQNp7traSqvvp4Sn_uaQ&#34;&gt;《喂我阿维》做了一个自行车战术的系列视频&lt;/a&gt;，这个系列的视频选择了一些实战的战况并结合了三维动画来解释各种战术，非常直观易懂，推荐大家观看。&lt;/p&gt;
&lt;h2 id=&#34;环法观赛中小白常问的问题&#34;&gt;环法观赛中小白常问的问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;为何约纳斯温格高（Jonas Vingegaard Rasmussen）外号鲨鱼佬？
温格高在进入职业比赛之前曾在鱼类加工厂干过一年左右的兼职，所以粉丝给他起了外号sha鱼佬。因为鲨鱼和sha鱼发音相同，所以就有了这个外号。其实也是为了规避社交平台的敏感词。&lt;/li&gt;
&lt;li&gt;为何提到波加查就会提到芬达？叫他芬达超人？
因为其他车手结束比赛大多会喝纯净水或者一些电解质饮料，或者一些我们不认识的功能饮料。而波加查喜欢比赛后喝芬达。不过今年很少看到他喝芬达了，不知道是不是没要到赞助费（狗头保命）。&lt;/li&gt;
&lt;li&gt;每次比赛都有四五个小时，车手怎么上厕所？
当然是站着解决了，哈哈。比赛开始时车速较慢，还可以停车在路边解决。比赛中段车速会很快，一旦停车将很难追上，通常这时车手会边骑边放水，如果你在直播中看到有在边上骑车并且骑行姿势奇怪的车手，那么他可能在放水。&lt;/li&gt;
&lt;li&gt;环法中有中国的车队吗？
很可惜，没有。目前也只有一位中国车手完成过环法，是在2014年来自捷安特·禧玛诺车队中国车手计成，以第164名，也是最后一名完成比赛。&lt;/li&gt;
&lt;li&gt;有的赛段在终点前许多车手为什么向路边扔水壶？
为了减轻负重，提高冲刺速度。&lt;/li&gt;
&lt;li&gt;卡文迪什（Mark CAVENDISH）外号由来？
&lt;ol&gt;
&lt;li&gt;盘爷：取自名字（CAVENDISH）的最后四个字母（Dish）。&lt;/li&gt;
&lt;li&gt;曼岛飞弹：因为卡文迪什是土生土长的曼岛人，并且速度飞快（曼岛以摩托赛曼岛TT著称）。&lt;/li&gt;
&lt;li&gt;卡胖：卡文迪什不擅爬坡，以及每逢佳节胖三斤的体质，为他招来了这个“雅号”。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;为何不想争赛段的车队也会在前面带风？为何要把主将带到最后三公里？
首先在集团前方相对来说较为安全，因为集团后方只能看到前面车手的屁股，对突发情况难以预判。其次因为在最后三公里发生摔车或者机械故障，成绩按照大集团的过线成绩计算，不会丢时间。
更新：UCI 已决定允许组织者和其他利益相关者试行要求修改所谓的“三公里”（或“冲刺区”）规则（《UCI 规则》第 2.6. 027 条），该规则适用于以下情况：比赛进入最后冲刺区，根据该规则，如果在公路赛段的最后三公里（不包括山顶终点）发生适当注意到的事件（例如跌倒、机械问题或爆胎），受影响的骑手的时间记入事件发生时与他一起骑车的骑手的时间。如果有正当理由，提出请求的组织者（或其他利益相关者）可以延长上述规则所考虑的距离，最多可以增加到五公里。任何变更都必须在比赛开始前获得同意。&lt;/li&gt;
&lt;li&gt;环法是不是只有一条线路？环绕法国国界吗？
不是，环法多个赛段，并且环法每年的线路都不一样，今年2024年就有21个赛段，并且也不是环绕法国边境线，有时候会经过法国以外的国家，比如今年2024年，就是从意大利的佛罗伦萨发车。&lt;/li&gt;
&lt;li&gt;比赛中的兔子是什么意思？为何有风不蹭要自己顶风骑？
之前回复哔站的一位的提问。兔子就是突围的车手，就是冲在最前面远离大集团的车手。每个车队在每场比赛中的战术不同这个目的就太多了，最简单的就是一个车手觉得自己今天状态特别好，那他就可以冲出去为了争夺赛段冠军，如果跟着大集团的话最后的冲刺会很难取胜。也有的车队想要拉赞助获得更高的曝光，那就会安排车手突围，这样可以获得更多的镜头增加曝光量。还有就是比赛一般都有荣誉衫，荣誉衫不仅仅只有成绩第一才有，也有冲刺得分最多的，爬坡得分最多的，那么就会有突围车手冲出去抢夺这些积分获得荣誉衫。再有就是只是为了打乱竞争对手的节奏，因为你突围的话，竞争对手就需要消耗大量体力追赶，很容易乱了节奏。当然你也肯定听过空中加油这个战术，在使用这个战术时就需要兔子这个角色，一般是实力较强的副将突围，在爬坡之前等自己的主将（在等待过程中就会降速恢复体力），然后在爬坡时为他破风，因为这时候竞争对手在追兔子的时候已经消耗了体力，而兔子已经稍有恢复，这时候就能将主将发射出去。&lt;/li&gt;
&lt;li&gt;车手把立位置是显示屏吗？还是一张贴纸？
是贴纸，标注了简单的赛段信息，最重要的是补给时间，比如图2就是第四赛段波加查车上贴的贴纸，标注了海拔图，还有在哪些位置进行补给。码表一般放在把立前方，突出的部分，有个架子。&lt;/li&gt;
&lt;li&gt;什么是十公里党？
就是只看比赛最后10公里的观众，因为平路赛段通常比较无聊，不会有什么进攻，只有最后几公里才有一些动作。&lt;/li&gt;
&lt;li&gt;个人计时赛（ITT）如何进行的？
所有未退赛的选手，都会参加。发车顺序是当前总成绩的倒序。发车间隔不确定（可能UCI有规定如果有知道具体计算方式的欢迎评论区告知），2024年环法第7赛段发车间隔为1分钟。和其他赛段不同，个人计时赛没有队友和其他人破风，完全需要比拼个人实力，用时最短者获胜。此外还有团队计时赛（TTT），是以车队为单位间隔发车，比拼车队整体实力，2024年环法没有团队计时赛。&lt;/li&gt;
&lt;li&gt;直播中屏幕上方的时间差是什么意思？
上方标志可以查看集团信息，黄色高亮框表示当然画面是哪个集团，比如现在就是表示画面是大集团。集团标题可能为荣誉衫的法语名称（比如Maillot Jaune是黄衫，Gr.是Group的缩写），领头羊（Tête de la Course，表示这个集团从开始就突围并一直保持领先未被追上过），明星车手的名字（比如图中的Carapaz和Johannessen），大集团（Peloton），追击集团（Chase）等等。显示的时间表示与突围集团的差距，所有的时间都是相对于突围集团的，不是相对于它的前一个集团。比如当前大集团比突围集团慢了约三分钟三十四秒，卡拉帕兹比突围集团慢了约十七秒。&lt;/li&gt;
&lt;li&gt;破风手在比赛前就定好了吗。每场比赛会轮流吗？
不是定好的，但是每个车队都会赛前定战术，赛场上变化很多，赛中车手也会听无线电里车队主管的安排。有一点是定的，主将几乎不会参与破风。&lt;/li&gt;
&lt;li&gt;最佳车队奖是如何评比的？
每个赛段结束后，根据每个车队的前三名最好成绩，计算车队的总成绩。时间最少的车队获得最佳车队奖。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;赞助商赞助的资源是否包含你提到的这些角色，是肯定包含的。但是具体赞助了什么，赞助多少，如何分配，也算是商业机密吧，我就不得而知了。我也分享一些我了解的信息。赞助商投入最大的还是在自行车上。每辆自行车至少都在一万美元以上。每个赛季都要投入一两百辆的车，这些装备肯定都是分配给车手的，此外赞助商通常还会赞助各个车队全球征战的差旅费，这就肯定包含所有后勤保障人员了。这里插一个有意思的，车队赞助商的投入不仅可以从车手装备看出差异，后勤保障车上也能管中窥豹。去年的冠军车队visma车队大巴堪比移动堡垒，移动之家，而现在只是职业车队乐透车队(Visma车队是世界级车队，比职业车队高一级)的大巴就略显“寒酸”了。感兴趣的话可以油管搜索关键词Inside Team bus。看看各个车队大巴的内部豪华设施，还是蛮有意思的。
关于赞助商的内容，我也是外行人，我给你发了一个链接，可以了解更多关于赞助的内容。也感谢你的提问，让我也学到了很多。&lt;/p&gt;
&lt;p&gt;第二个问题是关于如何获得比赛奖金以及奖金如何分配的。如何获得奖金，感兴趣的话可以直接站内搜索应该有朋友做总结，我就简单概括一下吧，奖金除了和比赛排名相关，和荣誉衫也是息息相关的。1. 最后总成绩的前三名肯定是有奖金的（第一名可以获得50万欧元的奖金），其实每个完赛的选手都有奖金。2. 每个赛段也会根据排名发放奖金，但是通常就只有前20名会有奖金。3. 每个荣誉衫每穿一天都会获得一次奖金，比如爬坡王圆点衫，每穿一天就能获得300欧元。4. 赛段中如果有标注等级的爬坡，那么率先通过这个爬坡的车手也会获得奖金。5. 组委会会为每个赛段中突围，进攻最积极的选手颁发敢斗奖，并在下个赛段用红色号码牌标记。拿敢斗奖也会获得2000欧元的奖金。6. 除了个人奖金，还有最佳车队奖，每一赛段结束后，根据每个车队的前三名最好成绩，计算车队的总成绩。时间最少的车队获得最佳车队奖（2800欧元）。7. 此外需要提醒的是，奖金只会发给真正获得荣誉衫的人，如果是顺延代穿荣誉衫，是不会获得奖金的。&lt;/p&gt;
&lt;p&gt;再说说奖金的分配，奖金从面子上讲，他是归属获得者个人的（最佳团队奖除外），但是里子上通常会根据内部规定进行分配。具体如何分配我也不够专业，就不误导你了。但是有一点你说的肯定没错，获奖一般离不开其他队友的帮助，肯定会按出力程度来分配。至于环法组委会如何发放奖金，发放到哪里，我也不太清楚，如果你有找到相关资料，欢迎分享给我。&lt;/p&gt;
&lt;h2 id=&#34;观赛工具&#34;&gt;观赛工具&lt;/h2&gt;
&lt;h3 id=&#34;环法官网&#34;&gt;&lt;a href=&#34;https://www.letour.fr/en/&#34;&gt;环法官网&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/8fd200df9d7f4927af93b6a2682ee206.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/8fd200df9d7f4927af93b6a2682ee206.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/85781085ead7d1a2856045f393d59806.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/85781085ead7d1a2856045f393d59806.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/cb422f01dbef804b065c91ba9ccf39f6.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/cb422f01dbef804b065c91ba9ccf39f6.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/01a2fd9a440f75c0a4408fd5b647c7bf.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/01a2fd9a440f75c0a4408fd5b647c7bf.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/0c70407a4e8cef8a1c4936a62da7a566.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/0c70407a4e8cef8a1c4936a62da7a566.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h3 id=&#34;tour-tracker&#34;&gt;Tour Tracker&lt;/h3&gt;
&lt;p&gt;网页版：https://live.thetourtracker.com/&lt;/p&gt;
&lt;p&gt;APP版本：Google Play Store 和 Apple App Store 搜索 Tour Tracker。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/419c3b57b5e4e60f90e43f89bb2ba9b4.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/419c3b57b5e4e60f90e43f89bb2ba9b4.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/dc727ffe4f928618451b2025d6d0b368.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/dc727ffe4f928618451b2025d6d0b368.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/2c700c2c9c1472910d0866c24bdab9c4.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/2c700c2c9c1472910d0866c24bdab9c4.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/94caa25c7ada5b0fc3b2ac9b62c7b8fd.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/94caa25c7ada5b0fc3b2ac9b62c7b8fd.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/670d46e6993018f2672960004f9d65e7.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/670d46e6993018f2672960004f9d65e7.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/c5cdc450fe4c7fa5f1ec8c99eaf911ff.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/c5cdc450fe4c7fa5f1ec8c99eaf911ff.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/6c099edf9dbd414c1aa8ab63c3246d7d.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/6c099edf9dbd414c1aa8ab63c3246d7d.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/d49747d9aad65e6cca31fad06b72fc0e.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/d49747d9aad65e6cca31fad06b72fc0e.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/2a8b7fe406cf72de8ff9378bcddd5bfa.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/2a8b7fe406cf72de8ff9378bcddd5bfa.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/3eab6470657e244cfe696065884c9936.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/3eab6470657e244cfe696065884c9936.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/a4881c186d1653a941978e539ca5be27.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/a4881c186d1653a941978e539ca5be27.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;奥运会公路车概况&#34;&gt;奥运会公路车概况&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;男子个人计时赛没有中国选手参加，但是男子公路赛有吕先景一位中国选手参加。吕先景目前效力于中国华兴-铭普洲际车队。2018年雅加达亚运会上，他获得男子山地自行车银牌，2019年环中国自行车赛，获得第二赛段冠军。期待吕先景在奥运会上取得好成绩。（PS：不用惊讶哦，是有环中国比赛的，只是2019年之后因为疫情就停办了，并且也没有复办的消息）&lt;/li&gt;
&lt;li&gt;女子个人计时赛有中国选手唐欣参加，同时她还会参加女子公路赛。她是中国第一位参加巴黎鲁贝女子自行车上并完赛的车手，也是中国第一位参加环西班牙女子自行车赛并完赛的车手，期待她在奥运会上取得好成绩。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;比赛规则简述&#34;&gt;比赛规则简述&lt;/h3&gt;
&lt;p&gt;男女个人计时赛&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一场定胜负的比赛，运动员在规定的时间内完成比赛，成绩最好的运动员获得金牌；&lt;/li&gt;
&lt;li&gt;运动员按照规定的间隔时间单独出发，以运动员到达终点的成绩优劣排名；&lt;/li&gt;
&lt;li&gt;发车时由同一名裁判员扶车；&lt;/li&gt;
&lt;li&gt;间隔1-2分钟发车，具体发车时间可在Tour Tracker，奥林匹克官网，ProCyclingStats等网站查看；&lt;/li&gt;
&lt;li&gt;即使追上了前面发车的车手，也不能相互领骑；&lt;/li&gt;
&lt;li&gt;在超车以及被超越过程中，运动员不得进入对手左右2米，前后25米的空间；&lt;/li&gt;
&lt;li&gt;队车不得在运动员前方行驶，只能在运动员后方25米外行驶；&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;男女公路赛&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一场定胜负的比赛，运动员在规定的时间内完成比赛，成绩最好的运动员获得金牌；&lt;/li&gt;
&lt;li&gt;发车位置按照签到顺序确定；&lt;/li&gt;
&lt;li&gt;比赛中可以跟风，可以互相帮助，交换食物和水以及工具等，但是不能相互推行；&lt;/li&gt;
&lt;li&gt;在赛程的前50公里和进入最后20公里后，不得进行补给，赛道上会有标识补给开始区域和补给结束区域；&lt;/li&gt;
&lt;li&gt;队车不得超越运动员，只有裁判同意才可以；&lt;/li&gt;
&lt;/ol&gt;
</description>
      <content:encoded><![CDATA[<h2 id="常见术语">常见术语</h2>
<ol>
<li>黄衫（Yellow jersey/Maillot Jaune）
黄衫是总成绩领先者的象征，穿上黄衫的车手就是比赛的领头羊。</li>
<li>绿衫（Green jersey/Maillot Vert）
绿衫代表冲刺积分的领先者，通常由擅长平地冲刺的车手穿着。</li>
<li>圆点衫（Polka dot jersey/Maillot à Pois Rouges）
圆点衫授予爬坡积分最高的车手，爬坡能力强的车手更有机会获得。</li>
<li>白衫（White jersey/Maillot Blanc）
白衫是最佳年轻车手（25岁以下）的象征，表现优异的年轻车手会穿上白衫。</li>
<li>突围/兔子（Breakaway）
指比赛中一小部分车手从主集团（Peloton）中突围出来，尝试抢占领先位置。</li>
<li>主集团（Peloton）
主集团是比赛中最大的车手队伍，大部分车手都会待在主集团里，节省体力。</li>
<li>冲刺（Sprint）
冲刺是比赛最后几百米的激烈竞争，冲刺手（Sprinter）们会在这时全力以赴，争夺赛段冠军。</li>
<li>掉队（Dropped）
被其他选手甩在后面，也被称为off the back或者out the back。</li>
<li>计时赛（Time Trial）
计时赛是车手单独出发，按时间计成绩的比赛形式，包括个人计时赛（ITT）和团队计时赛（TTT）。</li>
<li>总成绩（General Classification, GC）
总成绩是根据车手每个赛段的时间累加计算的，最终总时间最少的车手将获得黄衫。</li>
<li>皇后赛段（Queen Stage）
指的是能够决定多日赛最终排名的关键性山地赛段，通常有数座难度很大的山峰。</li>
<li>火车（Paceline）
指的是队友在前面做苦力，保护主将，为主将节省体力的战术。（对应的有冲刺火车或是山地火车）</li>
<li>跟风/蹭风/吸尾流（Draft）
在高速骑行过程中，车手的大部分体力是消耗在对抗空气阻力（风阻）上。因此会有车手骑在其他人或车子后方，来降低风阻，节省体力。</li>
<li>粘瓶（Sticky Bpttle）
选手在拿补给车的水壶时，会短暂获得补给车所带来的助力，以节省体力，通常三五秒之内都是被允许的，如果时间太长被裁判发现将会被罚款甚至取消成绩。</li>
<li>关门时间（Time limit）
在每天的比赛中，车手们必须在不超过当日赛段冠军用时的一定比例时间内完赛，否则将被取消比赛资格，不被获准在第二天的比赛时发车；确切的比例取决于赛段的类型、地形和速度；速度快时，在平地赛段中，比例会低至5%，而速度慢时，在山地赛段中，比例会达到16、17%。在某些情况下，赛事组织者有权酌情赦免一些车手，比如当有过大一部分车手无法在关门时间内完赛时。历史上也有过特例，一些大牌冲刺手被关门，然后组委会以扣冲刺积分的形式来放他们一马。</li>
<li>爬坡点等级（Mountain Climb Classification）
比赛中设置的爬坡抢分点，难度与级数由低至高为4、3、2、1、HC（顶级）；越高的级数代表爬坡长度越长、坡度越陡。</li>
<li>补给区 Feed Zone
比赛中设置一个区域，让车队提供车手饮食补给袋的地方。通常，车手不会在这个区域发动攻击。</li>
<li>垃圾丢弃区（Collection Zone）
UCI规定只能在固定的垃圾丢弃区扔垃圾，否则会被罚款。</li>
</ol>
<h2 id="自行车战术">自行车战术</h2>
<p>油管上有个台湾博主叫做<a href="https://www.youtube.com/watch?v=f1ncgvjB_z4&amp;list=PLa5LB6K0vQT3CzQNp7traSqvvp4Sn_uaQ">《喂我阿维》做了一个自行车战术的系列视频</a>，这个系列的视频选择了一些实战的战况并结合了三维动画来解释各种战术，非常直观易懂，推荐大家观看。</p>
<h2 id="环法观赛中小白常问的问题">环法观赛中小白常问的问题</h2>
<ol>
<li>为何约纳斯温格高（Jonas Vingegaard Rasmussen）外号鲨鱼佬？
温格高在进入职业比赛之前曾在鱼类加工厂干过一年左右的兼职，所以粉丝给他起了外号sha鱼佬。因为鲨鱼和sha鱼发音相同，所以就有了这个外号。其实也是为了规避社交平台的敏感词。</li>
<li>为何提到波加查就会提到芬达？叫他芬达超人？
因为其他车手结束比赛大多会喝纯净水或者一些电解质饮料，或者一些我们不认识的功能饮料。而波加查喜欢比赛后喝芬达。不过今年很少看到他喝芬达了，不知道是不是没要到赞助费（狗头保命）。</li>
<li>每次比赛都有四五个小时，车手怎么上厕所？
当然是站着解决了，哈哈。比赛开始时车速较慢，还可以停车在路边解决。比赛中段车速会很快，一旦停车将很难追上，通常这时车手会边骑边放水，如果你在直播中看到有在边上骑车并且骑行姿势奇怪的车手，那么他可能在放水。</li>
<li>环法中有中国的车队吗？
很可惜，没有。目前也只有一位中国车手完成过环法，是在2014年来自捷安特·禧玛诺车队中国车手计成，以第164名，也是最后一名完成比赛。</li>
<li>有的赛段在终点前许多车手为什么向路边扔水壶？
为了减轻负重，提高冲刺速度。</li>
<li>卡文迪什（Mark CAVENDISH）外号由来？
<ol>
<li>盘爷：取自名字（CAVENDISH）的最后四个字母（Dish）。</li>
<li>曼岛飞弹：因为卡文迪什是土生土长的曼岛人，并且速度飞快（曼岛以摩托赛曼岛TT著称）。</li>
<li>卡胖：卡文迪什不擅爬坡，以及每逢佳节胖三斤的体质，为他招来了这个“雅号”。</li>
</ol>
</li>
<li>为何不想争赛段的车队也会在前面带风？为何要把主将带到最后三公里？
首先在集团前方相对来说较为安全，因为集团后方只能看到前面车手的屁股，对突发情况难以预判。其次因为在最后三公里发生摔车或者机械故障，成绩按照大集团的过线成绩计算，不会丢时间。
更新：UCI 已决定允许组织者和其他利益相关者试行要求修改所谓的“三公里”（或“冲刺区”）规则（《UCI 规则》第 2.6. 027 条），该规则适用于以下情况：比赛进入最后冲刺区，根据该规则，如果在公路赛段的最后三公里（不包括山顶终点）发生适当注意到的事件（例如跌倒、机械问题或爆胎），受影响的骑手的时间记入事件发生时与他一起骑车的骑手的时间。如果有正当理由，提出请求的组织者（或其他利益相关者）可以延长上述规则所考虑的距离，最多可以增加到五公里。任何变更都必须在比赛开始前获得同意。</li>
<li>环法是不是只有一条线路？环绕法国国界吗？
不是，环法多个赛段，并且环法每年的线路都不一样，今年2024年就有21个赛段，并且也不是环绕法国边境线，有时候会经过法国以外的国家，比如今年2024年，就是从意大利的佛罗伦萨发车。</li>
<li>比赛中的兔子是什么意思？为何有风不蹭要自己顶风骑？
之前回复哔站的一位的提问。兔子就是突围的车手，就是冲在最前面远离大集团的车手。每个车队在每场比赛中的战术不同这个目的就太多了，最简单的就是一个车手觉得自己今天状态特别好，那他就可以冲出去为了争夺赛段冠军，如果跟着大集团的话最后的冲刺会很难取胜。也有的车队想要拉赞助获得更高的曝光，那就会安排车手突围，这样可以获得更多的镜头增加曝光量。还有就是比赛一般都有荣誉衫，荣誉衫不仅仅只有成绩第一才有，也有冲刺得分最多的，爬坡得分最多的，那么就会有突围车手冲出去抢夺这些积分获得荣誉衫。再有就是只是为了打乱竞争对手的节奏，因为你突围的话，竞争对手就需要消耗大量体力追赶，很容易乱了节奏。当然你也肯定听过空中加油这个战术，在使用这个战术时就需要兔子这个角色，一般是实力较强的副将突围，在爬坡之前等自己的主将（在等待过程中就会降速恢复体力），然后在爬坡时为他破风，因为这时候竞争对手在追兔子的时候已经消耗了体力，而兔子已经稍有恢复，这时候就能将主将发射出去。</li>
<li>车手把立位置是显示屏吗？还是一张贴纸？
是贴纸，标注了简单的赛段信息，最重要的是补给时间，比如图2就是第四赛段波加查车上贴的贴纸，标注了海拔图，还有在哪些位置进行补给。码表一般放在把立前方，突出的部分，有个架子。</li>
<li>什么是十公里党？
就是只看比赛最后10公里的观众，因为平路赛段通常比较无聊，不会有什么进攻，只有最后几公里才有一些动作。</li>
<li>个人计时赛（ITT）如何进行的？
所有未退赛的选手，都会参加。发车顺序是当前总成绩的倒序。发车间隔不确定（可能UCI有规定如果有知道具体计算方式的欢迎评论区告知），2024年环法第7赛段发车间隔为1分钟。和其他赛段不同，个人计时赛没有队友和其他人破风，完全需要比拼个人实力，用时最短者获胜。此外还有团队计时赛（TTT），是以车队为单位间隔发车，比拼车队整体实力，2024年环法没有团队计时赛。</li>
<li>直播中屏幕上方的时间差是什么意思？
上方标志可以查看集团信息，黄色高亮框表示当然画面是哪个集团，比如现在就是表示画面是大集团。集团标题可能为荣誉衫的法语名称（比如Maillot Jaune是黄衫，Gr.是Group的缩写），领头羊（Tête de la Course，表示这个集团从开始就突围并一直保持领先未被追上过），明星车手的名字（比如图中的Carapaz和Johannessen），大集团（Peloton），追击集团（Chase）等等。显示的时间表示与突围集团的差距，所有的时间都是相对于突围集团的，不是相对于它的前一个集团。比如当前大集团比突围集团慢了约三分钟三十四秒，卡拉帕兹比突围集团慢了约十七秒。</li>
<li>破风手在比赛前就定好了吗。每场比赛会轮流吗？
不是定好的，但是每个车队都会赛前定战术，赛场上变化很多，赛中车手也会听无线电里车队主管的安排。有一点是定的，主将几乎不会参与破风。</li>
<li>最佳车队奖是如何评比的？
每个赛段结束后，根据每个车队的前三名最好成绩，计算车队的总成绩。时间最少的车队获得最佳车队奖。</li>
</ol>
<p>赞助商赞助的资源是否包含你提到的这些角色，是肯定包含的。但是具体赞助了什么，赞助多少，如何分配，也算是商业机密吧，我就不得而知了。我也分享一些我了解的信息。赞助商投入最大的还是在自行车上。每辆自行车至少都在一万美元以上。每个赛季都要投入一两百辆的车，这些装备肯定都是分配给车手的，此外赞助商通常还会赞助各个车队全球征战的差旅费，这就肯定包含所有后勤保障人员了。这里插一个有意思的，车队赞助商的投入不仅可以从车手装备看出差异，后勤保障车上也能管中窥豹。去年的冠军车队visma车队大巴堪比移动堡垒，移动之家，而现在只是职业车队乐透车队(Visma车队是世界级车队，比职业车队高一级)的大巴就略显“寒酸”了。感兴趣的话可以油管搜索关键词Inside Team bus。看看各个车队大巴的内部豪华设施，还是蛮有意思的。
关于赞助商的内容，我也是外行人，我给你发了一个链接，可以了解更多关于赞助的内容。也感谢你的提问，让我也学到了很多。</p>
<p>第二个问题是关于如何获得比赛奖金以及奖金如何分配的。如何获得奖金，感兴趣的话可以直接站内搜索应该有朋友做总结，我就简单概括一下吧，奖金除了和比赛排名相关，和荣誉衫也是息息相关的。1. 最后总成绩的前三名肯定是有奖金的（第一名可以获得50万欧元的奖金），其实每个完赛的选手都有奖金。2. 每个赛段也会根据排名发放奖金，但是通常就只有前20名会有奖金。3. 每个荣誉衫每穿一天都会获得一次奖金，比如爬坡王圆点衫，每穿一天就能获得300欧元。4. 赛段中如果有标注等级的爬坡，那么率先通过这个爬坡的车手也会获得奖金。5. 组委会会为每个赛段中突围，进攻最积极的选手颁发敢斗奖，并在下个赛段用红色号码牌标记。拿敢斗奖也会获得2000欧元的奖金。6. 除了个人奖金，还有最佳车队奖，每一赛段结束后，根据每个车队的前三名最好成绩，计算车队的总成绩。时间最少的车队获得最佳车队奖（2800欧元）。7. 此外需要提醒的是，奖金只会发给真正获得荣誉衫的人，如果是顺延代穿荣誉衫，是不会获得奖金的。</p>
<p>再说说奖金的分配，奖金从面子上讲，他是归属获得者个人的（最佳团队奖除外），但是里子上通常会根据内部规定进行分配。具体如何分配我也不够专业，就不误导你了。但是有一点你说的肯定没错，获奖一般离不开其他队友的帮助，肯定会按出力程度来分配。至于环法组委会如何发放奖金，发放到哪里，我也不太清楚，如果你有找到相关资料，欢迎分享给我。</p>
<h2 id="观赛工具">观赛工具</h2>
<h3 id="环法官网"><a href="https://www.letour.fr/en/">环法官网</a></h3>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/8fd200df9d7f4927af93b6a2682ee206.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/8fd200df9d7f4927af93b6a2682ee206.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/85781085ead7d1a2856045f393d59806.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/85781085ead7d1a2856045f393d59806.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/cb422f01dbef804b065c91ba9ccf39f6.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/cb422f01dbef804b065c91ba9ccf39f6.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/01a2fd9a440f75c0a4408fd5b647c7bf.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/01a2fd9a440f75c0a4408fd5b647c7bf.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/0c70407a4e8cef8a1c4936a62da7a566.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/0c70407a4e8cef8a1c4936a62da7a566.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h3 id="tour-tracker">Tour Tracker</h3>
<p>网页版：https://live.thetourtracker.com/</p>
<p>APP版本：Google Play Store 和 Apple App Store 搜索 Tour Tracker。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/419c3b57b5e4e60f90e43f89bb2ba9b4.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/419c3b57b5e4e60f90e43f89bb2ba9b4.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/dc727ffe4f928618451b2025d6d0b368.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/dc727ffe4f928618451b2025d6d0b368.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/2c700c2c9c1472910d0866c24bdab9c4.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/2c700c2c9c1472910d0866c24bdab9c4.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/94caa25c7ada5b0fc3b2ac9b62c7b8fd.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/94caa25c7ada5b0fc3b2ac9b62c7b8fd.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/670d46e6993018f2672960004f9d65e7.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/670d46e6993018f2672960004f9d65e7.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/c5cdc450fe4c7fa5f1ec8c99eaf911ff.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/c5cdc450fe4c7fa5f1ec8c99eaf911ff.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/6c099edf9dbd414c1aa8ab63c3246d7d.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/6c099edf9dbd414c1aa8ab63c3246d7d.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/d49747d9aad65e6cca31fad06b72fc0e.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/d49747d9aad65e6cca31fad06b72fc0e.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/2a8b7fe406cf72de8ff9378bcddd5bfa.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/2a8b7fe406cf72de8ff9378bcddd5bfa.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/3eab6470657e244cfe696065884c9936.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/3eab6470657e244cfe696065884c9936.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/a4881c186d1653a941978e539ca5be27.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/07/07/a4881c186d1653a941978e539ca5be27.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="奥运会公路车概况">奥运会公路车概况</h2>
<ol>
<li>男子个人计时赛没有中国选手参加，但是男子公路赛有吕先景一位中国选手参加。吕先景目前效力于中国华兴-铭普洲际车队。2018年雅加达亚运会上，他获得男子山地自行车银牌，2019年环中国自行车赛，获得第二赛段冠军。期待吕先景在奥运会上取得好成绩。（PS：不用惊讶哦，是有环中国比赛的，只是2019年之后因为疫情就停办了，并且也没有复办的消息）</li>
<li>女子个人计时赛有中国选手唐欣参加，同时她还会参加女子公路赛。她是中国第一位参加巴黎鲁贝女子自行车上并完赛的车手，也是中国第一位参加环西班牙女子自行车赛并完赛的车手，期待她在奥运会上取得好成绩。</li>
</ol>
<h3 id="比赛规则简述">比赛规则简述</h3>
<p>男女个人计时赛</p>
<ol>
<li>一场定胜负的比赛，运动员在规定的时间内完成比赛，成绩最好的运动员获得金牌；</li>
<li>运动员按照规定的间隔时间单独出发，以运动员到达终点的成绩优劣排名；</li>
<li>发车时由同一名裁判员扶车；</li>
<li>间隔1-2分钟发车，具体发车时间可在Tour Tracker，奥林匹克官网，ProCyclingStats等网站查看；</li>
<li>即使追上了前面发车的车手，也不能相互领骑；</li>
<li>在超车以及被超越过程中，运动员不得进入对手左右2米，前后25米的空间；</li>
<li>队车不得在运动员前方行驶，只能在运动员后方25米外行驶；</li>
</ol>
<p>男女公路赛</p>
<ol>
<li>一场定胜负的比赛，运动员在规定的时间内完成比赛，成绩最好的运动员获得金牌；</li>
<li>发车位置按照签到顺序确定；</li>
<li>比赛中可以跟风，可以互相帮助，交换食物和水以及工具等，但是不能相互推行；</li>
<li>在赛程的前50公里和进入最后20公里后，不得进行补给，赛道上会有标识补给开始区域和补给结束区域；</li>
<li>队车不得超越运动员，只有裁判同意才可以；</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>ZWIFT 使用 Tips</title>
      <link>https://lifeislife.cn/posts/zwift%E4%BD%BF%E7%94%A8tips/</link>
      <pubDate>Sun, 17 Dec 2023 13:24:55 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/zwift%E4%BD%BF%E7%94%A8tips/</guid>
      <description>&lt;h1 id=&#34;安装与配置&#34;&gt;安装与配置&lt;/h1&gt;
&lt;p&gt;登录 Zwift 官网下载安装包，安装完成后打开，输入邮箱和密码登录。但是我的电脑离骑行台较远，蓝牙很不稳定，Zwift 还有一个配套的手机 App，叫 Companion，可以在谷歌商店安装。安装后打开登录。Zwift PC 客户端登录后在配对装置页面左上角选择“透过手机进行配对”，正常情况下手机端会自动弹出配对页面。记得打开手机的蓝牙开关。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/12/17/0573bf51587d55e549ac5fd4719733b4.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/12/17/0573bf51587d55e549ac5fd4719733b4.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/12/17/6fb1f8bb10562bb55eb8b7eddb97a0ce.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/12/17/6fb1f8bb10562bb55eb8b7eddb97a0ce.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h1 id=&#34;道具功能介绍&#34;&gt;道具功能介绍&lt;/h1&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/9f7b084ae99d7eed0ba7e01aea33d59c.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/9f7b084ae99d7eed0ba7e01aea33d59c.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/5d91493b1d349bbbcc46b16d65699d36.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/5d91493b1d349bbbcc46b16d65699d36.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/ba3a70faede05b47fffab9e13e6139ff.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/ba3a70faede05b47fffab9e13e6139ff.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h1 id=&#34;常见问题&#34;&gt;常见问题&lt;/h1&gt;
&lt;h2 id=&#34;启动后闪退&#34;&gt;启动后闪退&lt;/h2&gt;
&lt;p&gt;将输入法切换为英文模式再重新启动。&lt;/p&gt;
&lt;h2 id=&#34;没有其他玩家只有自己&#34;&gt;没有其他玩家，只有自己&lt;/h2&gt;
&lt;p&gt;挂全局代理重新启动。&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h1 id="安装与配置">安装与配置</h1>
<p>登录 Zwift 官网下载安装包，安装完成后打开，输入邮箱和密码登录。但是我的电脑离骑行台较远，蓝牙很不稳定，Zwift 还有一个配套的手机 App，叫 Companion，可以在谷歌商店安装。安装后打开登录。Zwift PC 客户端登录后在配对装置页面左上角选择“透过手机进行配对”，正常情况下手机端会自动弹出配对页面。记得打开手机的蓝牙开关。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/12/17/0573bf51587d55e549ac5fd4719733b4.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/12/17/0573bf51587d55e549ac5fd4719733b4.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/12/17/6fb1f8bb10562bb55eb8b7eddb97a0ce.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/12/17/6fb1f8bb10562bb55eb8b7eddb97a0ce.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h1 id="道具功能介绍">道具功能介绍</h1>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/9f7b084ae99d7eed0ba7e01aea33d59c.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/9f7b084ae99d7eed0ba7e01aea33d59c.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/5d91493b1d349bbbcc46b16d65699d36.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/5d91493b1d349bbbcc46b16d65699d36.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/ba3a70faede05b47fffab9e13e6139ff.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2024/06/13/ba3a70faede05b47fffab9e13e6139ff.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h1 id="常见问题">常见问题</h1>
<h2 id="启动后闪退">启动后闪退</h2>
<p>将输入法切换为英文模式再重新启动。</p>
<h2 id="没有其他玩家只有自己">没有其他玩家，只有自己</h2>
<p>挂全局代理重新启动。</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
