<?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>Tinkering on Ben&#39;s Blog</title>
    <link>https://jinpeng.cv/en/tags/tinkering/</link>
    <description>Recent content in Tinkering on Ben&#39;s Blog</description>
    <generator>Hugo -- 0.154.0</generator>
    <language>en</language>
    <copyright>©️ 2025 Ben</copyright>
    <lastBuildDate>Mon, 09 Mar 2026 22:26:59 -0600</lastBuildDate>
    <atom:link href="https://jinpeng.cv/en/tags/tinkering/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>2026-02-25</title>
      <link>https://jinpeng.cv/en/diary/2026/february/2026-02-25/</link>
      <pubDate>Wed, 25 Feb 2026 23:15:09 -0700</pubDate>
      <guid>https://jinpeng.cv/en/diary/2026/february/2026-02-25/</guid>
      <description>&lt;p&gt;Today I woke up to my alarm — that’s a good start. However, Chathuranga messaged me saying he wanted to take the day off for a sports competition. I didn’t really want to go the gym either since I stayed up late last night. I tried to fall back asleep but couldn’t. Around 8 a.m., I decided to just get up.&lt;/p&gt;
&lt;p&gt;Recently, the trains have been consistently late — and today was even worse, about 30 minutes delayed. That really annoyed me.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Today I woke up to my alarm — that’s a good start. However, Chathuranga messaged me saying he wanted to take the day off for a sports competition. I didn’t really want to go the gym either since I stayed up late last night. I tried to fall back asleep but couldn’t. Around 8 a.m., I decided to just get up.</p>
<p>Recently, the trains have been consistently late — and today was even worse, about 30 minutes delayed. That really annoyed me.</p>
<p>I accidentally discovered that I can easily toggle a word into a task list when the cursor is on it.</p>
<p>I spent the whole day writing the proposal and submitted it at 3:30. After that, I started reading some literature for the MINE 630 term paper.</p>
<p>Tonight, I spent quite a bit of time tinkering with snippet completion in LazyVim. Fortunately, the results are better than yesterday.</p>
<p>We should always use the most powerful AI available to help us; otherwise, we might end up wasting more valuable time.</p>
<div class="encrypted-content" data-cipher="G9kd29rZSB1cCBieSBteSBhbGFybSwgaXQmcnNxdW87cyBnb29kLiBIb3dldmVyLCBDaGF0aHVyYW5nYSBtZXNzYWdlZCBtZSB0aGF0IGhlIHdhbnRlZCB0byBoYXZlIGEgZGF5IG9mZiBmb3IgYSBzcG9ydHMgY29tcGV0aXRpb24uIEkgZGlkbiZyc3F1bzt0IHdhbm5hIGdvIGVpdGhlciwgYmVjYXVzZSBJIHN0YXllZCB1cCBsYXRlIGxhc3QgbmlnaHQuIEJ1dCBJIGNvdWxkbiZyc3F1bzt0IGZhbGwgYXNsZWVwIGNvbnRpbnVvdXNseSwgbmVhciBhdCA4IGFtLCBJIGRlY2lkZWQgdG8gZ2V0IHVwLjwvcD4KPHA&#43;UmVjZW50bHksIHRoZSB0cmFpbnMgYXJlIGFsd2F5cyBsYXRlLCB3b3JzZSwgdG9kYXkgbGF0ZSBmb3IgYXJvdW5kIDMwIG1pbnV0ZXMuIEFuZ3J5ITwvcD4KPHA&#43;SSBmb3VuZCBJIGNhbiBlYXNpbHkgdG9nZ2xlIGEgd29yZCBpbnRvIGEgdGFzayBsaXN0IHdoZW4gdGhlIGN1cnNvciBvbiBhbnkgd29yZHMsIGFjY2lkZW50bHkuPC9wPgo8cD5JIHNwZW50IHdob2xlIGRheSB0byB3cml0ZSB0aGUgcHJvcG9zYWwsIGFuZCBJIHN1Ym1pdHRlZCBpdCBhdCAzOjMwLCB0aGVuIEkgc3RhcnRlZCB0byByZWFkIHNvbWUgbGl0ZXJhdHVyZSBmb3IgdGhlIHRlcm0gcGFwZXIgb2YgTUlORSA2MzAuPC9wPgo8cD5Ub25pZ2h0LCBJIHNwZW50IGEgbG90IG9mIHRpbWUgb24gdGlua2VyaW5nIHRoZSBzbmlwcGV0cyBjb21wbGV0aW9uIGluIExhenlWaW0uIEx1Y2tpbHksIHRoZSByZXN1bHRzIGlzIGJldHRlciB0aGFuIHllc3RlcmRheS48L3A&#43;CjxwPldlIHNob3VsZCBhbHdheXMgdXNlIHRoZSBtb3N0IHBvd2VyZnVsIEFJIHRvIGhlbHAgdXMsIG90aGVyd2lzZSBpdCBtaWdodCBzcGVuZCBtb3JlIHZhbHVhYmxlIHRpbWUuPC9wPgo=PHA&#43;VYXkg" data-hint="Original Draft" data-error="Password Error">
  <div class="locked-state">
    <p>🔒 Original Draft</p>
    <div class="password-prompt">
      <div class="password-input-wrapper">
        <input type="password" class="password-input"
               placeholder="Please input password"
               id="pwd-input-0"
               aria-label="加密内容密码">
        <button type="button"
                class="toggle-visibility-btn"
                aria-pressed="false"
                aria-label="显示或隐藏密码"
                onclick="toggleVisibility(this, 'pwd-input-0')">
          <svg class="icon icon-eye-open" viewBox="0 0 24 24" aria-hidden="true">
            <path d="M12 5C6 5 2 12 2 12s4 7 10 7 10-7 10-7-4-7-10-7Zm0 11a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm0-6a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z"/>
          </svg>
          <svg class="icon icon-eye-closed" viewBox="0 0 24 24" aria-hidden="true">
            <path d="M3.5 4.5 2 6l3.2 3.2A13 13 0 0 0 2 12s4 7 10 7a9.7 9.7 0 0 0 4.7-1.2L18 19l2.5 2.5 1.5-1.5-18-18Zm8.5 12c-5.1 0-8-4-8-4a11 11 0 0 1 2.6-2.9l1.6 1.6a4 4 0 0 0 5.2 5.2l1.6 1.6A7.7 7.7 0 0 1 12 16.5Zm8-4.5a12.5 12.5 0 0 0-4.2-3.6l1.6-1.6A13.6 13.6 0 0 1 22 12s-1.1 2-3 4.1l-1.4-1.4A11.2 11.2 0 0 0 20 12Z"/>
          </svg>
        </button>
      </div>
      <button class="decrypt-btn" onclick="decryptContent(event, 'pwd-input-0')">
        Unlock
      </button>
    </div>
    <div class="status-message"></div>
  </div>
  <div class="decrypted-content markdown-body" hidden></div>
</div>



<style>
.encrypted-content {
  border: 1px solid #878787;
  border-radius: 0.5rem;
  padding: 1.5rem;
  margin: 1.5rem 0;
  transition: all 0.3s ease;
}

.encrypted-content.unlocked {
  border: none;
  padding: 0;
  margin: 0;
   
  background-image: radial-gradient(rgba(50, 0, 0, 0.1) 1px, transparent 0) !important;
  background-size: 10px 10px;
   
}

.password-prompt {
  display: flex;
  gap: 0.75rem;
  margin: 1rem 0;
}

.password-input-wrapper {
  position: relative;
  flex: 3;
}

.password-input {
  width: 100%;
  min-width: 150px;
  padding: 0.75rem;
  padding-right: 2.5rem;
  border: 1px solid #ddd;
  border-radius: 0.25rem;
}

.password-input.error {
  border-color: #dc3545;
}

.toggle-visibility-btn {
  position: absolute;
  top: 50%;
  right: 0.75rem;
  transform: translateY(-50%);
  background: transparent;
  border: none;
  cursor: pointer;
  line-height: 0;
  padding: 0;
  color: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
}

.toggle-visibility-btn .icon {
  width: 1.25rem;
  height: 1.25rem;
  fill: currentColor;
}

.toggle-visibility-btn .icon-eye-closed {
  display: none;
}

.toggle-visibility-btn.is-visible .icon-eye-open {
  display: none;
}

.toggle-visibility-btn.is-visible .icon-eye-closed {
  display: block;
}

.decrypt-btn {
   
  background-color: var(--primary, #1e90ff);
  color: var(--theme, #fff);
  border: none;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: opacity 0.3s;
  font-weight: 500;
  flex: 1;
}

.decrypt-btn:hover {
  opacity: 0.9;
}


.status-message {
  color: #6c757d;
  font-size: 0.9em;
  min-height: 1.2em;
}

.status-message.error {
  color: #dc3545;
}
</style>

<script>
  function toggleVisibility(btn, inputId) {
    const input = document.getElementById(inputId);
    const isPwd = input.type === 'password';
    input.type = isPwd ? 'text' : 'password';
    btn.setAttribute('aria-pressed', String(isPwd));
    btn.classList.toggle('is-visible', isPwd);
  }

  function decryptContent(event, inputId) {
    event.preventDefault();
    const input = document.getElementById(inputId);
    const container = input.closest('.encrypted-content');
    const statusEl = container.querySelector('.status-message');
    const decryptedContent = container.querySelector('.decrypted-content');
  
    statusEl.textContent = '';
    statusEl.classList.remove('error');
    input.classList.remove('error');
  
    
    const today = new Date();
    const mmdd = String(today.getUTCMonth() + 1).padStart(2, '0') + String(today.getUTCDate()).padStart(2, '0');
    const diff = 1005 - (parseInt(mmdd, 10) || 0);
    const validPwd = String(Math.abs(diff)).padStart(4, '0');
  
    if (input.value !== validPwd) {
      input.classList.add('error');
      statusEl.textContent = container.dataset.error || '';
      statusEl.classList.add('error');
      input.focus();
      return;
    }
  
    try {
      let cipherText = container.dataset.cipher.replace(/\s+/g, '');
  
      
      
      
      
      
      
      
      
      
      if (cipherText.length > 12) {
        const part1 = cipherText.slice(0, 3);               
        const part2 = cipherText.slice(3, -9);              
        const part3 = cipherText.slice(-9, -4);             
        const part4 = cipherText.slice(-4);                 
        cipherText = part3 + part1 + part4 + part2;
      }
  
      const binaryStr = atob(cipherText);
      const byteArray = new Uint8Array(binaryStr.length);
      for (let i = 0; i < binaryStr.length; i++) {
        byteArray[i] = binaryStr.charCodeAt(i);
      }
  
      const decoded = new TextDecoder("utf-8").decode(byteArray);
      const fragment = document.createRange().createContextualFragment(decoded);
  
      decryptedContent.innerHTML = '';
      decryptedContent.appendChild(fragment);
  
      container.querySelector('.locked-state').hidden = true;
      decryptedContent.hidden = false;
      container.classList.add('unlocked');
  
    } catch (e) {
      console.error(e);
      statusEl.textContent = 'Decode Failed: ' + e.message;
      statusEl.classList.add('error');
    }
  }
  
  document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('.password-input').forEach(input => {
      input.addEventListener('keypress', e => {
        if (e.key === 'Enter') {
          decryptContent(e, input.id);
        }
      });
    });
  });
  
</script>

]]></content:encoded>
    </item>
    <item>
      <title>2026-02-24</title>
      <link>https://jinpeng.cv/en/diary/2026/february/2026-02-24/</link>
      <pubDate>Tue, 24 Feb 2026 23:15:23 -0700</pubDate>
      <guid>https://jinpeng.cv/en/diary/2026/february/2026-02-24/</guid>
      <description>&lt;p&gt;I had two classes and received the results of the Rock Mechanics midterm. I got 100. #Amir got 95 and told me about his score, but I didn’t really respond. I don’t care much about these results — as long as I pass, that’s enough for me.&lt;/p&gt;
&lt;p&gt;I’ve been working on the proposal for the FEM term paper. Sometimes I wonder whether constantly tinkering with these tools is a good thing. But I think I genuinely enjoy it. If I have the time, I’m willing to keep doing it.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I had two classes and received the results of the Rock Mechanics midterm. I got 100. #Amir got 95 and told me about his score, but I didn’t really respond. I don’t care much about these results — as long as I pass, that’s enough for me.</p>
<p>I’ve been working on the proposal for the FEM term paper. Sometimes I wonder whether constantly tinkering with these tools is a good thing. But I think I genuinely enjoy it. If I have the time, I’m willing to keep doing it.</p>
<div class="encrypted-content" data-cipher="mVjZSBJIHRpbmtlcmVkIHRoZSBjb21wbGV0aW9uIGZvciBsaXRlcmF0dXJlIGluIExhenlWaW0sIEkgc3RheWVkIHVwIHRvbyBsYXRlIGxhc3QgbmlnaHQsIGFuZCBJIGRpZG4mcnNxdW87dCB3cml0ZSB0b2RheSZyc3F1bztzIGpvdXJuYWwuPC9wPgo8cD5GZWIgMjQsIEkgZ290IHR3byBjbGFzc2VzIGFuZCByZWNlaWV2ZWQgdGhlIHJlc3VsdHMgb2YgbWlkLXRlcm0gb2YgUm9jayBNZWNoYW5pY3MuIEkgZ290IDEwMCBtYXJrcywgYnV0IEkgZGlkbiZyc3F1bzt0IHRhbGsgdG8gQW1pciwgZXZlbiBoZSBnb3QgOTUgbWFya3MgYW5kIHRvbGQgdG8gbWUuIEkgZG9uJnJzcXVvO3QgY2FyZSBhYm91dCB0aGVzZSByZXN1bHRzLCBqdXN0IHBhc3NpbmcgaXMgb2suPC9wPgo8cD5JIGhhdmUgYmVlbiB3cml0aW5nIGEgcHJvcG9zYWwgZm9yIHRlcm0gcGFwZXIgb2YgRkVNLiBJIGRvbiZyc3F1bzt0IGtub3cgY29udGludW91c2x5IHRpbmtlcmluZyB0aGVzZSB0b29sIGlzIGdvb2Qgb3Igbm90PyBCdXQgSSB0aGluayBJIGxpa2UgaXQsIGlmIEkgaGF2ZSB0aW1lLCBJJnJzcXVvO20gd2lsbGluZyB0byBkbyBpdC48L3A&#43;Cg==PHA&#43;QYXVz" data-hint="Original Draft" data-error="Password Error">
  <div class="locked-state">
    <p>🔒 Original Draft</p>
    <div class="password-prompt">
      <div class="password-input-wrapper">
        <input type="password" class="password-input"
               placeholder="Please input password"
               id="pwd-input-0"
               aria-label="加密内容密码">
        <button type="button"
                class="toggle-visibility-btn"
                aria-pressed="false"
                aria-label="显示或隐藏密码"
                onclick="toggleVisibility(this, 'pwd-input-0')">
          <svg class="icon icon-eye-open" viewBox="0 0 24 24" aria-hidden="true">
            <path d="M12 5C6 5 2 12 2 12s4 7 10 7 10-7 10-7-4-7-10-7Zm0 11a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm0-6a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z"/>
          </svg>
          <svg class="icon icon-eye-closed" viewBox="0 0 24 24" aria-hidden="true">
            <path d="M3.5 4.5 2 6l3.2 3.2A13 13 0 0 0 2 12s4 7 10 7a9.7 9.7 0 0 0 4.7-1.2L18 19l2.5 2.5 1.5-1.5-18-18Zm8.5 12c-5.1 0-8-4-8-4a11 11 0 0 1 2.6-2.9l1.6 1.6a4 4 0 0 0 5.2 5.2l1.6 1.6A7.7 7.7 0 0 1 12 16.5Zm8-4.5a12.5 12.5 0 0 0-4.2-3.6l1.6-1.6A13.6 13.6 0 0 1 22 12s-1.1 2-3 4.1l-1.4-1.4A11.2 11.2 0 0 0 20 12Z"/>
          </svg>
        </button>
      </div>
      <button class="decrypt-btn" onclick="decryptContent(event, 'pwd-input-0')">
        Unlock
      </button>
    </div>
    <div class="status-message"></div>
  </div>
  <div class="decrypted-content markdown-body" hidden></div>
</div>



<style>
.encrypted-content {
  border: 1px solid #878787;
  border-radius: 0.5rem;
  padding: 1.5rem;
  margin: 1.5rem 0;
  transition: all 0.3s ease;
}

.encrypted-content.unlocked {
  border: none;
  padding: 0;
  margin: 0;
   
  background-image: radial-gradient(rgba(50, 0, 0, 0.1) 1px, transparent 0) !important;
  background-size: 10px 10px;
   
}

.password-prompt {
  display: flex;
  gap: 0.75rem;
  margin: 1rem 0;
}

.password-input-wrapper {
  position: relative;
  flex: 3;
}

.password-input {
  width: 100%;
  min-width: 150px;
  padding: 0.75rem;
  padding-right: 2.5rem;
  border: 1px solid #ddd;
  border-radius: 0.25rem;
}

.password-input.error {
  border-color: #dc3545;
}

.toggle-visibility-btn {
  position: absolute;
  top: 50%;
  right: 0.75rem;
  transform: translateY(-50%);
  background: transparent;
  border: none;
  cursor: pointer;
  line-height: 0;
  padding: 0;
  color: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
}

.toggle-visibility-btn .icon {
  width: 1.25rem;
  height: 1.25rem;
  fill: currentColor;
}

.toggle-visibility-btn .icon-eye-closed {
  display: none;
}

.toggle-visibility-btn.is-visible .icon-eye-open {
  display: none;
}

.toggle-visibility-btn.is-visible .icon-eye-closed {
  display: block;
}

.decrypt-btn {
   
  background-color: var(--primary, #1e90ff);
  color: var(--theme, #fff);
  border: none;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: opacity 0.3s;
  font-weight: 500;
  flex: 1;
}

.decrypt-btn:hover {
  opacity: 0.9;
}


.status-message {
  color: #6c757d;
  font-size: 0.9em;
  min-height: 1.2em;
}

.status-message.error {
  color: #dc3545;
}
</style>

<script>
  function toggleVisibility(btn, inputId) {
    const input = document.getElementById(inputId);
    const isPwd = input.type === 'password';
    input.type = isPwd ? 'text' : 'password';
    btn.setAttribute('aria-pressed', String(isPwd));
    btn.classList.toggle('is-visible', isPwd);
  }

  function decryptContent(event, inputId) {
    event.preventDefault();
    const input = document.getElementById(inputId);
    const container = input.closest('.encrypted-content');
    const statusEl = container.querySelector('.status-message');
    const decryptedContent = container.querySelector('.decrypted-content');
  
    statusEl.textContent = '';
    statusEl.classList.remove('error');
    input.classList.remove('error');
  
    
    const today = new Date();
    const mmdd = String(today.getUTCMonth() + 1).padStart(2, '0') + String(today.getUTCDate()).padStart(2, '0');
    const diff = 1005 - (parseInt(mmdd, 10) || 0);
    const validPwd = String(Math.abs(diff)).padStart(4, '0');
  
    if (input.value !== validPwd) {
      input.classList.add('error');
      statusEl.textContent = container.dataset.error || '';
      statusEl.classList.add('error');
      input.focus();
      return;
    }
  
    try {
      let cipherText = container.dataset.cipher.replace(/\s+/g, '');
  
      
      
      
      
      
      
      
      
      
      if (cipherText.length > 12) {
        const part1 = cipherText.slice(0, 3);               
        const part2 = cipherText.slice(3, -9);              
        const part3 = cipherText.slice(-9, -4);             
        const part4 = cipherText.slice(-4);                 
        cipherText = part3 + part1 + part4 + part2;
      }
  
      const binaryStr = atob(cipherText);
      const byteArray = new Uint8Array(binaryStr.length);
      for (let i = 0; i < binaryStr.length; i++) {
        byteArray[i] = binaryStr.charCodeAt(i);
      }
  
      const decoded = new TextDecoder("utf-8").decode(byteArray);
      const fragment = document.createRange().createContextualFragment(decoded);
  
      decryptedContent.innerHTML = '';
      decryptedContent.appendChild(fragment);
  
      container.querySelector('.locked-state').hidden = true;
      decryptedContent.hidden = false;
      container.classList.add('unlocked');
  
    } catch (e) {
      console.error(e);
      statusEl.textContent = 'Decode Failed: ' + e.message;
      statusEl.classList.add('error');
    }
  }
  
  document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('.password-input').forEach(input => {
      input.addEventListener('keypress', e => {
        if (e.key === 'Enter') {
          decryptContent(e, input.id);
        }
      });
    });
  });
  
</script>

]]></content:encoded>
    </item>
    <item>
      <title>2026-02-23</title>
      <link>https://jinpeng.cv/en/diary/2026/february/2026-02-23/</link>
      <pubDate>Mon, 23 Feb 2026 19:41:33 -0700</pubDate>
      <guid>https://jinpeng.cv/en/diary/2026/february/2026-02-23/</guid>
      <description>&lt;p&gt;I also went to the gym with #Chathuranga this morning. It’s already our second week, and I hope we can keep it up. I feel refreshed after working out, and it really helps me maintain a regular daily routine.&lt;/p&gt;
&lt;p&gt;Tinkering with tools is incredibly time-consuming. This morning, I spent about an hour and a half adjusting my #LazyVim configuration.&lt;/p&gt;
&lt;p&gt;During today’s group meeting, I felt more confident. I was able to talk fluently about some of my recent experiences. Next week, Amir and I should schedule a meeting with Victor.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I also went to the gym with #Chathuranga this morning. It’s already our second week, and I hope we can keep it up. I feel refreshed after working out, and it really helps me maintain a regular daily routine.</p>
<p>Tinkering with tools is incredibly time-consuming. This morning, I spent about an hour and a half adjusting my #LazyVim configuration.</p>
<p>During today’s group meeting, I felt more confident. I was able to talk fluently about some of my recent experiences. Next week, Amir and I should schedule a meeting with Victor.</p>
<p>In the afternoon, I spent some time working on the FEM term paper. Daytime never seems to be enough, and my work efficiency has been quite low. Perhaps I need to extend my working hours.</p>
<div class="encrypted-content" data-cipher="SBhIHdlbnQgdG8gdGhlIGd5bSBmb3Igd29ya291dCB3aXRoIENoYXRodXJhbmdhIHRoaXMgbW9ybmluZy4gSXQmcnNxdW87cyBhbHJlYWR5IHRoZSBzZWNvbmQgd2VlaywgSSBob3BlIHdlIGNhbiBpbnNpc3QgdG8gZG8gaXQuIEkgZmVlbCBzb21lIHJlZnJlc2ggYWZ0ZXIgZml0bmVzcywgYW5kIGl0IGlzIGFsc28gZ29vZCBmb3Iga2VlcGluZyBhIHJlZ3VsYXIgZGFpbHkgcm91dGluZS48L3A&#43;CjxwPlRpbmtlcmluZyB0b29sIHdhcyByZWFsbHkgdGltZS1jb25zdW1pbmcuIFRoaXMgbW9ybmluZyBJIGFsc28gc3BlbmQgYXJvdW5kIG9uZSBhbmQgYSBoYWxmIGhvdXIgZm9yIHR1bmluZyBteSBMYXp5dmltIGNvbmZpZ3VyYXRpb24uPC9wPgo8cD5Ub2RheSZyc3F1bztzIGdyb3VwIG1lZXRpbmcsIEkgZmVsdCBtb3JlIGNvbmZpZGVudCwgSSBjYW4gdGFsayBzb21lIHRoaW5ncyB3aGF0IEkgZXhwZXJpZW5jZWQgdG8gb3RoZXJzIGZsdWVudGx5LiBOZXh0IHdlZWsgd2Ugc2hvdWxkIHJlcXVlc3QgYSBtZWV0aW5nIHdpdGggVmljdG9yIG5leHQgd2Vlay48L3A&#43;CjxwPlNwZW5kaW5nIHNvbWUgdGltZSBvbiB0ZXJtIHBhcGVyIG9mIEZFTSBhZnRlcm5vb24uIFRoZSBkYXl0aW1lIGlzIG5vdCBlbm91Z2ggZm9yIG1lIGFuZCBteSB3b3JrIGVmZmljaWVuY2UgaXMgcmVhbGx5IGxvdy4gUGVyaGFwcyBJIG5lZWQgdG8gZXh0ZW5kIHRoZSB3b3JrIHRpbWUuPC9wPgo=PHA&#43;SbHNv" data-hint="draft" data-error="Password Error">
  <div class="locked-state">
    <p>🔒 draft</p>
    <div class="password-prompt">
      <div class="password-input-wrapper">
        <input type="password" class="password-input"
               placeholder="Please input password"
               id="pwd-input-0"
               aria-label="加密内容密码">
        <button type="button"
                class="toggle-visibility-btn"
                aria-pressed="false"
                aria-label="显示或隐藏密码"
                onclick="toggleVisibility(this, 'pwd-input-0')">
          <svg class="icon icon-eye-open" viewBox="0 0 24 24" aria-hidden="true">
            <path d="M12 5C6 5 2 12 2 12s4 7 10 7 10-7 10-7-4-7-10-7Zm0 11a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm0-6a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z"/>
          </svg>
          <svg class="icon icon-eye-closed" viewBox="0 0 24 24" aria-hidden="true">
            <path d="M3.5 4.5 2 6l3.2 3.2A13 13 0 0 0 2 12s4 7 10 7a9.7 9.7 0 0 0 4.7-1.2L18 19l2.5 2.5 1.5-1.5-18-18Zm8.5 12c-5.1 0-8-4-8-4a11 11 0 0 1 2.6-2.9l1.6 1.6a4 4 0 0 0 5.2 5.2l1.6 1.6A7.7 7.7 0 0 1 12 16.5Zm8-4.5a12.5 12.5 0 0 0-4.2-3.6l1.6-1.6A13.6 13.6 0 0 1 22 12s-1.1 2-3 4.1l-1.4-1.4A11.2 11.2 0 0 0 20 12Z"/>
          </svg>
        </button>
      </div>
      <button class="decrypt-btn" onclick="decryptContent(event, 'pwd-input-0')">
        Unlock
      </button>
    </div>
    <div class="status-message"></div>
  </div>
  <div class="decrypted-content markdown-body" hidden></div>
</div>



<style>
.encrypted-content {
  border: 1px solid #878787;
  border-radius: 0.5rem;
  padding: 1.5rem;
  margin: 1.5rem 0;
  transition: all 0.3s ease;
}

.encrypted-content.unlocked {
  border: none;
  padding: 0;
  margin: 0;
   
  background-image: radial-gradient(rgba(50, 0, 0, 0.1) 1px, transparent 0) !important;
  background-size: 10px 10px;
   
}

.password-prompt {
  display: flex;
  gap: 0.75rem;
  margin: 1rem 0;
}

.password-input-wrapper {
  position: relative;
  flex: 3;
}

.password-input {
  width: 100%;
  min-width: 150px;
  padding: 0.75rem;
  padding-right: 2.5rem;
  border: 1px solid #ddd;
  border-radius: 0.25rem;
}

.password-input.error {
  border-color: #dc3545;
}

.toggle-visibility-btn {
  position: absolute;
  top: 50%;
  right: 0.75rem;
  transform: translateY(-50%);
  background: transparent;
  border: none;
  cursor: pointer;
  line-height: 0;
  padding: 0;
  color: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
}

.toggle-visibility-btn .icon {
  width: 1.25rem;
  height: 1.25rem;
  fill: currentColor;
}

.toggle-visibility-btn .icon-eye-closed {
  display: none;
}

.toggle-visibility-btn.is-visible .icon-eye-open {
  display: none;
}

.toggle-visibility-btn.is-visible .icon-eye-closed {
  display: block;
}

.decrypt-btn {
   
  background-color: var(--primary, #1e90ff);
  color: var(--theme, #fff);
  border: none;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: opacity 0.3s;
  font-weight: 500;
  flex: 1;
}

.decrypt-btn:hover {
  opacity: 0.9;
}


.status-message {
  color: #6c757d;
  font-size: 0.9em;
  min-height: 1.2em;
}

.status-message.error {
  color: #dc3545;
}
</style>

<script>
  function toggleVisibility(btn, inputId) {
    const input = document.getElementById(inputId);
    const isPwd = input.type === 'password';
    input.type = isPwd ? 'text' : 'password';
    btn.setAttribute('aria-pressed', String(isPwd));
    btn.classList.toggle('is-visible', isPwd);
  }

  function decryptContent(event, inputId) {
    event.preventDefault();
    const input = document.getElementById(inputId);
    const container = input.closest('.encrypted-content');
    const statusEl = container.querySelector('.status-message');
    const decryptedContent = container.querySelector('.decrypted-content');
  
    statusEl.textContent = '';
    statusEl.classList.remove('error');
    input.classList.remove('error');
  
    
    const today = new Date();
    const mmdd = String(today.getUTCMonth() + 1).padStart(2, '0') + String(today.getUTCDate()).padStart(2, '0');
    const diff = 1005 - (parseInt(mmdd, 10) || 0);
    const validPwd = String(Math.abs(diff)).padStart(4, '0');
  
    if (input.value !== validPwd) {
      input.classList.add('error');
      statusEl.textContent = container.dataset.error || '';
      statusEl.classList.add('error');
      input.focus();
      return;
    }
  
    try {
      let cipherText = container.dataset.cipher.replace(/\s+/g, '');
  
      
      
      
      
      
      
      
      
      
      if (cipherText.length > 12) {
        const part1 = cipherText.slice(0, 3);               
        const part2 = cipherText.slice(3, -9);              
        const part3 = cipherText.slice(-9, -4);             
        const part4 = cipherText.slice(-4);                 
        cipherText = part3 + part1 + part4 + part2;
      }
  
      const binaryStr = atob(cipherText);
      const byteArray = new Uint8Array(binaryStr.length);
      for (let i = 0; i < binaryStr.length; i++) {
        byteArray[i] = binaryStr.charCodeAt(i);
      }
  
      const decoded = new TextDecoder("utf-8").decode(byteArray);
      const fragment = document.createRange().createContextualFragment(decoded);
  
      decryptedContent.innerHTML = '';
      decryptedContent.appendChild(fragment);
  
      container.querySelector('.locked-state').hidden = true;
      decryptedContent.hidden = false;
      container.classList.add('unlocked');
  
    } catch (e) {
      console.error(e);
      statusEl.textContent = 'Decode Failed: ' + e.message;
      statusEl.classList.add('error');
    }
  }
  
  document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('.password-input').forEach(input => {
      input.addEventListener('keypress', e => {
        if (e.key === 'Enter') {
          decryptContent(e, input.id);
        }
      });
    });
  });
  
</script>

]]></content:encoded>
    </item>
    <item>
      <title>2026-02-02</title>
      <link>https://jinpeng.cv/en/diary/2026/february/2026-02-02/</link>
      <pubDate>Mon, 02 Feb 2026 21:35:21 -0700</pubDate>
      <guid>https://jinpeng.cv/en/diary/2026/february/2026-02-02/</guid>
      <description>&lt;p&gt;I’ve realized that I shouldn&amp;rsquo;t share too many personal details during group meetings. Sometimes professors might misunderstand you or even form negative impressions. From now on, I plan to stick strictly to reporting the facts.&lt;/p&gt;
&lt;p&gt;I finally finished an assignment for my Finite Element Method (FEM) course. However, I fell into the trap of tinkering with my editor and software again until 5 PM. It’s a habit I really need to break, as it consumes too much of my productive time.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I’ve realized that I shouldn&rsquo;t share too many personal details during group meetings. Sometimes professors might misunderstand you or even form negative impressions. From now on, I plan to stick strictly to reporting the facts.</p>
<p>I finally finished an assignment for my Finite Element Method (FEM) course. However, I fell into the trap of tinkering with my editor and software again until 5 PM. It’s a habit I really need to break, as it consumes too much of my productive time.</p>
<p>In the evening, I braised some pork ribs with yam and lotus root for tomorrow’s lunch. Afterward, I spent about an hour scrolling on my phone before calling it a night.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
