<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Latest News | Xu Lab</title><link>https://xulab-zotero-test.pages.dev/en/post/</link><atom:link href="https://xulab-zotero-test.pages.dev/en/post/index.xml" rel="self" type="application/rss+xml"/><description>Latest News</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Sat, 04 Jul 2026 00:00:00 +0000</lastBuildDate><image><url>https://xulab-zotero-test.pages.dev/media/icon_hu_9d9b593248f3c06d.png</url><title>Latest News</title><link>https://xulab-zotero-test.pages.dev/en/post/</link></image><item><title>Literature for Group Meeting</title><link>https://xulab-zotero-test.pages.dev/en/post/literature-for-group-meeting/</link><pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate><guid>https://xulab-zotero-test.pages.dev/en/post/literature-for-group-meeting/</guid><description>&lt;p>This page is auto-synced from a Zotero group library and organized into Reported, Assigned, and Unread. Presenters can claim papers in the Unread section, and new papers can be added to the Zotero library from both the Assigned and Unread sections. Click the User Guide button for detailed instructions.&lt;/p>
&lt;style>
.zotero-board { margin: 2rem 0; font-size: 15px; }
.zotero-tools { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 16px; }
.zotero-filter-label { color: #374151; font-weight: 600; font-size: 14px; }
.zotero-filter-input { flex: 1; min-width: 240px; padding: 9px 12px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 14px; box-sizing: border-box; }
.zotero-filter-input:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37,99,235,.12); }
.zotero-filter-clear { padding: 9px 14px; border: 1px solid #d1d5db; background: #fff; color: #374151; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 600; }
.zotero-filter-clear:hover { background: #f9fafb; }
.zotero-guide-btn { padding: 9px 16px; background: #f3f4f6; color: #374151; border: 1px solid #d1d5db; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 600; white-space: nowrap; }
.zotero-guide-btn:hover { background: #e5e7eb; }
.zotero-tabs { display: none; gap: 8px; flex-wrap: wrap; border-bottom: 1px solid #e5e7eb; padding-bottom: 10px; margin-bottom: 18px; }
.zotero-tab { padding: 6px 14px; border-radius: 999px; cursor: pointer; border: 1px solid #d1d5db; background: #fff; color: #374151; font-weight: 600; transition: all .15s; }
.zotero-tab.active { background: #2563eb; color: #fff; border-color: #2563eb; }
.zotero-content { display: none; }
.zotero-content.active { display: block; }
.zotero-empty { color: #9ca3af; padding: 1.5rem 0; }
.paper-card { border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px 18px; margin-bottom: 14px; background: #fff; }
.paper-card.paper-match { background: #fef9c3; border-color: #f59e0b; }
.paper-title { font-weight: 700; font-size: 16px; line-height: 1.45; color: #111827; user-select: none; display: flex; align-items: flex-start; gap: 4px; flex-wrap: wrap; }
.paper-title.paper-expandable { cursor: pointer; }
.paper-title.paper-expandable:hover { color: #2563eb; }
.paper-toggle { display: inline-block; width: 1.2em; font-size: 14px; color: #6b7280; transition: transform .15s; flex: 0 0 auto; }
.paper-toggle.expanded { transform: rotate(90deg); }
.paper-authors { color: #4b5563; margin-top: 4px; font-size: 13.5px; }
.paper-meta { color: #6b7280; margin-top: 4px; font-size: 13px; }
.paper-meta a { color: #2563eb; text-decoration: none; margin-left: 10px; }
.paper-meta a:hover { text-decoration: underline; }
.paper-abstract { color: #4b5563; margin-top: 10px; font-size: 13.5px; line-height: 1.6; white-space: pre-line; display: none; }
.paper-badges, .paper-claim-meta { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.paper-badge, .paper-chip { display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 600; }
.paper-badge-external { background: #fef3c7; color: #92400e; }
.paper-badge-passed { background: #fee2e2; color: #991b1b; }
.paper-badge-claimed { background: #dbeafe; color: #1e40af; }
.paper-chip { background: #f3f4f6; color: #374151; }
.paper-claim { margin-top: 14px; padding-top: 12px; border-top: 1px dashed #e5e7eb; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.zotero-claim-btn { display: inline-block; padding: 7px 16px; background: #2563eb; color: #fff; border: none; border-radius: 7px; cursor: pointer; font-size: 13.5px; font-weight: 600; }
.zotero-claim-btn:hover { background: #1d4ed8; }
.zotero-undo-btn, .zotero-delete-btn { display: inline-block; padding: 7px 16px; background: #fff; color: #dc2626; border: 1px solid #dc2626; border-radius: 7px; cursor: pointer; font-size: 13.5px; font-weight: 600; }
.zotero-undo-btn:hover, .zotero-delete-btn:hover { background: #fee2e2; }
.zotero-claim-info { display: inline-block; font-size: 13px; color: #1e40af; }
.zotero-upload-form { border: 1px dashed #93c5fd; border-radius: 8px; padding: 18px; margin-bottom: 18px; background: #eff6ff; }
.zotero-upload-form h4 { margin: 0 0 12px 0; font-size: 15px; color: #1e40af; }
.zotero-upload-form .form-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; align-items: center; }
.zotero-upload-form input { padding: 8px 12px; border: 1px solid #d1d5db; border-radius: 6px; font-size: 14px; box-sizing: border-box; }
.zotero-upload-form input[type=text] { flex: 1; min-width: 200px; }
.zotero-upload-form input[type=date] { width: 160px; }
.zotero-upload-form .form-error { color: #dc2626; font-size: 13px; margin-top: 6px; min-height: 18px; }
.zotero-upload-form .form-submit { padding: 8px 20px; background: #2563eb; color: #fff; border: none; border-radius: 7px; cursor: pointer; font-size: 14px; font-weight: 600; }
.zotero-upload-form .form-submit:hover { background: #1d4ed8; }
.zotero-upload-form .form-label { font-size: 13.5px; font-weight: 600; color: #374151; margin-right: 4px; white-space: nowrap; }
.zotero-batch-btn { display: inline-block; padding: 8px 16px; background: #f3f4f6; color: #374151; border: 1px solid #d1d5db; border-radius: 7px; cursor: pointer; font-size: 13px; font-weight: 600; margin-left: 10px; }
.zotero-batch-btn:hover { background: #e5e7eb; }
.zotero-guide-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,.4); z-index: 1000; display: flex; justify-content: flex-end; }
.zotero-guide-panel { width: 420px; max-width: 90vw; height: 100%; background: #fff; box-shadow: -2px 0 12px rgba(0,0,0,.15); display: flex; flex-direction: column; overflow: hidden; }
.zotero-guide-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; border-bottom: 1px solid #e5e7eb; }
.zotero-guide-title { margin: 0; font-size: 16px; color: #1e40af; }
.zotero-guide-close { background: none; border: none; font-size: 24px; color: #6b7280; cursor: pointer; line-height: 1; }
.zotero-guide-close:hover { color: #111827; }
.zotero-guide-body { padding: 20px; overflow-y: auto; font-size: 14px; line-height: 1.7; color: #374151; }
.zotero-guide-body h5 { margin: 16px 0 8px; font-size: 14px; color: #1e40af; }
.zotero-guide-body p { margin: 0 0 10px; }
.zotero-guide-body ul { margin: 0 0 10px; padding-left: 20px; }
.zotero-guide-body li { margin-bottom: 4px; }
.zotero-confirm-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,.4); z-index: 1001; display: flex; justify-content: center; align-items: center; }
.zotero-confirm-dialog { background: #fff; border-radius: 12px; padding: 24px; max-width: 520px; width: 90%; max-height: 80vh; overflow-y: auto; box-shadow: 0 8px 30px rgba(0,0,0,.2); }
.zotero-confirm-title { margin: 0 0 16px; font-size: 16px; color: #1e40af; }
.zotero-confirm-list { margin-bottom: 16px; }
.zotero-confirm-item { padding: 10px 14px; border: 1px solid #e5e7eb; border-radius: 8px; margin-bottom: 8px; background: #f9fafb; }
.zotero-confirm-item .doi { font-size: 13px; color: #6b7280; word-break: break-all; }
.zotero-confirm-item .title { font-weight: 600; font-size: 14px; color: #111827; margin-top: 4px; }
.zotero-confirm-actions { display: flex; gap: 10px; justify-content: flex-end; }
.zotero-confirm-cancel { padding: 8px 20px; background: #f3f4f6; color: #374151; border: 1px solid #d1d5db; border-radius: 7px; cursor: pointer; font-size: 14px; font-weight: 600; }
.zotero-confirm-ok { padding: 8px 20px; background: #2563eb; color: #fff; border: none; border-radius: 7px; cursor: pointer; font-size: 14px; font-weight: 600; }
.zotero-confirm-ok:hover { background: #1d4ed8; }
.zotero-batch-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,.4); z-index: 1001; display: flex; justify-content: center; align-items: center; }
.zotero-batch-dialog { background: #fff; border-radius: 12px; padding: 24px; max-width: 520px; width: 90%; box-shadow: 0 8px 30px rgba(0,0,0,.2); }
.zotero-batch-title { margin: 0 0 12px; font-size: 16px; color: #1e40af; }
.zotero-batch-input { width: 100%; min-height: 120px; padding: 10px 12px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 14px; font-family: monospace; box-sizing: border-box; resize: vertical; }
.zotero-batch-input:focus { outline: none; border-color: #2563eb; }
.zotero-batch-hint { margin: 6px 0 16px; font-size: 12px; color: #6b7280; }
.zotero-batch-actions { display: flex; gap: 10px; justify-content: flex-end; }
.zotero-batch-cancel { padding: 8px 20px; background: #f3f4f6; color: #374151; border: 1px solid #d1d5db; border-radius: 7px; cursor: pointer; font-size: 14px; font-weight: 600; }
.zotero-batch-submit { padding: 8px 20px; background: #2563eb; color: #fff; border: none; border-radius: 7px; cursor: pointer; font-size: 14px; font-weight: 600; }
.zotero-batch-submit:hover { background: #1d4ed8; }
.zotero-confirm-ok:disabled, .zotero-batch-submit:disabled { opacity: .6; cursor: not-allowed; }
&lt;/style>
&lt;div class="zotero-board" data-lang="en" data-claim-category="待阅读" data-repo="Helloxiaolaodi/xu-research-lab.github.io">
&lt;div class="zotero-tools">
&lt;label class="zotero-filter-label" for="zotero-filter-input">&lt;/label>
&lt;input id="zotero-filter-input" type="text" class="zotero-filter-input" autocomplete="off" />
&lt;button type="button" class="zotero-filter-clear">&lt;/button>
&lt;button type="button" class="zotero-guide-btn">&lt;/button>
&lt;/div>
&lt;div class="zotero-tabs" role="tablist" style="display:none;">&lt;/div>
&lt;div class="zotero-loading" style="display:none;">&lt;/div>
&lt;div class="zotero-container" style="display:none;">&lt;/div>
&lt;/div>
&lt;div class="zotero-guide-overlay" style="display:none;">
&lt;div class="zotero-guide-panel">
&lt;div class="zotero-guide-header">
&lt;h3 class="zotero-guide-title">&lt;/h3>
&lt;button type="button" class="zotero-guide-close">&amp;#215;&lt;/button>
&lt;/div>
&lt;div class="zotero-guide-body">&lt;/div>
&lt;/div>
&lt;/div>
&lt;div class="zotero-confirm-overlay" style="display:none;">
&lt;div class="zotero-confirm-dialog">
&lt;h4 class="zotero-confirm-title">&lt;/h4>
&lt;div class="zotero-confirm-list">&lt;/div>
&lt;div class="zotero-confirm-actions">
&lt;button type="button" class="zotero-confirm-cancel">&lt;/button>
&lt;button type="button" class="zotero-confirm-ok">&lt;/button>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div class="zotero-batch-overlay" style="display:none;">
&lt;div class="zotero-batch-dialog">
&lt;h4 class="zotero-batch-title">&lt;/h4>
&lt;textarea class="zotero-batch-input" rows="8">&lt;/textarea>
&lt;p class="zotero-batch-hint">&lt;/p>
&lt;div class="zotero-batch-actions">
&lt;button type="button" class="zotero-batch-cancel">&lt;/button>
&lt;button type="button" class="zotero-batch-submit">&lt;/button>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;script>
(function () {
var board = document.querySelector('.zotero-board');
if (!board) return;
var CATEGORY_CLAIMED = '\u5DF2\u8BA4\u9886';
var CATEGORY_REPORTED = '\u5DF2\u6C47\u62A5';
var CATEGORY_TO_READ = '\u5F85\u9605\u8BFB';
var toolsEl = board.querySelector('.zotero-tools');
var filterLabel = board.querySelector('.zotero-filter-label');
var filterInput = board.querySelector('.zotero-filter-input');
var filterClear = board.querySelector('.zotero-filter-clear');
var guideBtn = board.querySelector('.zotero-guide-btn');
var loadingEl = board.querySelector('.zotero-loading');
var tabsEl = board.querySelector('.zotero-tabs');
var container = board.querySelector('.zotero-container');
var dataNode = board.querySelector('.zotero-embedded-data');
var lang = board.getAttribute('data-lang') || 'zh';
var claimCat = board.getAttribute('data-claim-category') || CATEGORY_TO_READ;
var guideOverlay = board.parentElement.querySelector('.zotero-guide-overlay');
var guideTitle = guideOverlay.querySelector('.zotero-guide-title');
var guideBody = guideOverlay.querySelector('.zotero-guide-body');
var guideClose = guideOverlay.querySelector('.zotero-guide-close');
var confirmOverlay = board.parentElement.querySelector('.zotero-confirm-overlay');
var confirmTitle = confirmOverlay.querySelector('.zotero-confirm-title');
var confirmList = confirmOverlay.querySelector('.zotero-confirm-list');
var confirmCancel = confirmOverlay.querySelector('.zotero-confirm-cancel');
var confirmOk = confirmOverlay.querySelector('.zotero-confirm-ok');
var batchOverlay = board.parentElement.querySelector('.zotero-batch-overlay');
var batchTitle = batchOverlay.querySelector('.zotero-batch-title');
var batchInput = batchOverlay.querySelector('.zotero-batch-input');
var batchHint = batchOverlay.querySelector('.zotero-batch-hint');
var batchCancel = batchOverlay.querySelector('.zotero-batch-cancel');
var batchSubmitBtn = batchOverlay.querySelector('.zotero-batch-submit');
var state = { data: {}, activeCategory: null, query: '', refreshTimer: null, isRefreshing: false };
var i18n = {
zh: {
loading: '\u6B63\u5728\u540C\u6B65\u6587\u732E\u5E93\uFF0C\u8BF7\u7A0D\u5019...',
empty: '\u8BE5\u5206\u7C7B\u4E0B\u6682\u65E0\u6587\u732E\u3002',
filterLabel: '\u7B5B\u9009',
filterPlaceholder: '',
filterClear: '\u6E05\u9664',
guideBtn: '\u4F7F\u7528\u6307\u5357',
guideTitle: '\u4F7F\u7528\u6307\u5357',
guideContent: '&lt;h5>\u4E00\u3001\u8BA4\u9886\u6587\u732E&lt;/h5>&lt;p>\u5728\u2308\u5F85\u9605\u8BFB\u230B \u533A\u70B9\u51FB\u201C\u8BA4\u9886\u201D\uFF0C\u8F93\u5165\u6C47\u62A5\u4EBA\u59D3\u540D\u548C\u6C47\u62A5\u65E5\u671F\u6765\u8BA4\u9886\u6587\u732E\uFF0C\u6587\u732E\u4F1A\u81EA\u52A8\u79FB\u81F3 \u2308\u5DF2\u8BA4\u9886\u230B \u533A\u3002&lt;/p>&lt;h5>\u4E8C\u3001\u6DFB\u52A0\u6587\u732E&lt;/h5>&lt;p>\uFF081\uFF09\u5728\u2308\u5F85\u9605\u8BFB\u230B\u533A\u8F93\u5165\u5355\u4E2A\u6587\u732E\u7684DOI\u5E76\u70B9\u51FB\u201C\u63D0\u4EA4\u201D\uFF0C\u5B8C\u6210\u6DFB\u52A0\u65B0\u6587\u732E\uFF1B\u4E5F\u53EF\u4F7F\u7528\u6279\u91CF\u5BFC\u5165 DOI \u529F\u80FD\uFF0C\u5373\u4E00\u6B21\u6027\u6DFB\u52A0\u591A\u7BC7\u6587\u732E\u3002&lt;/p>&lt;p>\uFF082\uFF09\u5C1A\u672A\u7EB3\u5165 Zotero \u6587\u732E\u5E93\u7684\u6587\u732E\uFF0C\u6C47\u62A5\u4EBA\u9700\u5728\u2308\u5DF2\u8BA4\u9886\u230B \u533A\u8F93\u5165\u5355\u7BC7\u6587\u732E\u7684DOI\u3001\u6C47\u62A5\u4EBA\u59D3\u540D\u548C\u6C47\u62A5\u65E5\u671F\uFF0C\u6587\u732E\u4F1A\u81EA\u52A8\u79FB\u81F3 \u2308\u5DF2\u8BA4\u9886\u230B \u533A\u3002&lt;/p>&lt;h5>\u4E09\u3001\u64A4\u9500\u6587\u732E&lt;/h5>&lt;p>\u5DF2\u8BA4\u9886\u7684\u6587\u732E\u53EF\u70B9\u51FB\u201C\u64A4\u9500\u8BA4\u9886\u201D\uFF0C\u9000\u56DE\u2308\u5F85\u9605\u8BFB\u230B \u533A\uFF1B\u65B0\u6DFB\u52A0\u7684\u6587\u732E\u53EF\u70B9\u51FB\u201C\u64A4\u9500\u201D\uFF0C\u4ECEZotero\u6587\u732E\u5E93\u4E2D\u5220\u9664\u3002&lt;/p>', confirmTitle: '\u786E\u8BA4\u63D0\u4EA4\u4FE1\u606F',
confirmOk: '\u786E\u8BA4\u65E0\u8BEF',
confirmCancel: '\u53D6\u6D88',
batchTitle: '\u6279\u91CF\u5BFC\u5165 DOI',
batchHint: '\u6BCF\u884C\u4E00\u4E2A DOI\uFF0C\u6216\u7528\u5206\u53F7\u3001\u7A7A\u683C\u7B49\u5206\u9694\uFF0C\u4F8B\u5982\uFF1A10.1234/abc ; 10.5678/def',
batchSubmit: '\u63D0\u4EA4',
batchCancel: '\u53D6\u6D88',
batchAdd: '\u6279\u91CF\u5BFC\u5165',
viewSource: '\u67E5\u770B\u539F\u6587',
claimBtn: '\u8BA4\u9886',
undoBtn: '\u64A4\u9500\u8BA4\u9886',
deleteBtn: '\u64A4\u9500',
claimTitle: '\u6587\u732E\u8BA4\u9886',
claimPaper: '\u51C6\u5907\u8BA4\u9886\u7684\u6587\u732E\uFF1A',
inputName: '\u8BF7\u8F93\u5165\u6C47\u62A5\u4EBA\u59D3\u540D\uFF08\u683C\u5F0F\uFF1ASan Zhang\uFF0C\u540D\u5728\u524D\u59D3\u5728\u540E\uFF0C\u9996\u5B57\u6BCD\u5927\u5199\uFF09\uFF1A',
inputDate: '\u8BF7\u8F93\u5165\u6C47\u62A5\u65E5\u671F\uFF08\u683C\u5F0F\uFF1AYYYY-MM-DD\uFF09\uFF1A',
invalidDate: '\u8BF7\u8F93\u5165\u6709\u6548\u65E5\u671F\uFF0C\u683C\u5F0F\u4E3A YYYY-MM-DD\u3002',
claimCancel: '\u5DF2\u53D6\u6D88\u3002',
claimOk: '\u8BA4\u9886\u6210\u529F\u3002',
undoOk: '\u5DF2\u64A4\u9500\u3002',
undoConfirm: '\u786E\u8BA4\u64A4\u9500\u5F53\u524D\u8BA4\u9886\u5417\uFF1F',
deleteConfirm: '\u786E\u8BA4\u64A4\u9500\u8FD9\u7BC7\u5DF2\u6DFB\u52A0\u7684\u6587\u732E\u5417\uFF1F\u8FD9\u4F1A\u4ECE Zotero \u7FA4\u7EC4\u4E2D\u5220\u9664\u8BE5\u6761\u76EE\u3002',
uploadTitleToRead: '\u6DFB\u52A0\u65B0\u6587\u732E\u5230 Zotero \u6587\u732E\u5E93',
uploadTitleClaimed: '\u6DFB\u52A0\u65B0\u6587\u732E\u5230 Zotero \u6587\u732E\u5E93',
uploadDoiLabel: 'DOI\uFF08\u5FC5\u586B\uFF0C\u4F8B\u5982 10.1016/...\uFF09',
uploadNameLabel: '\u6C47\u62A5\u4EBA\u59D3\u540D\uFF08\u683C\u5F0F\uFF1ASan Zhang\uFF09\uFF1A',
uploadDateLabel: '\u6C47\u62A5\u65E5\u671F',
uploadSubmit: '\u63D0\u4EA4',
uploadSubmitting: '\u63D0\u4EA4\u4E2D...',
uploadSuccess: '\u63D0\u4EA4\u6210\u529F\uFF0C\u6587\u732E\u5DF2\u52A0\u5165 Zotero \u7FA4\u7EC4\u3002',
uploadErrorDoi: '\u8BF7\u8F93\u5165 DOI\uFF0C\u4E14\u5FC5\u987B\u4EE5 10. \u5F00\u5934\u3002',
uploadErrorName: '\u8BF7\u8F93\u5165\u6C47\u62A5\u4EBA\u59D3\u540D\u3002',
uploadErrorDate: '\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6C47\u62A5\u65E5\u671F\u3002',
saveError: '\u63D0\u4EA4\u5931\u8D25\uFF1A',
badgeExternal: '\u5DF2\u6DFB\u52A0',
badgePassed: '\u5DF2\u8FC7\u671F',
badgeClaimed: '\u5DF2\u8BA4\u9886',
badgeReported: '\u5DF2\u6C47\u62A5',
claimantLabel: '\u6C47\u62A5\u4EBA',
dateLabel: '\u6C47\u62A5\u65E5\u671F',
loadFailed: '\u6587\u732E\u6570\u636E\u52A0\u8F7D\u5931\u8D25\u3002',
untitled: '\u65E0\u6807\u9898',
categoryLabels: { '\u5DF2\u6C47\u62A5': '\u5DF2\u6C47\u62A5', '\u5DF2\u8BA4\u9886': '\u5DF2\u8BA4\u9886', '\u5F85\u9605\u8BFB': '\u5F85\u9605\u8BFB' }
},
en: {
loading: 'Loading the literature library, please wait...',
empty: 'No papers in this category yet.',
filterLabel: 'Filter',
filterPlaceholder: '',
filterClear: 'Clear',
guideBtn: 'User Guide',
guideTitle: 'User Guide',
guideContent: '&lt;h5>1. Claim Papers&lt;/h5>&lt;p>In the Unread section, click &amp;quot;Claim&amp;quot; and enter the presenter name and report date. The paper will move to Assigned automatically.&lt;/p>&lt;h5>2. Add Papers&lt;/h5>&lt;p>(1) In the Unread section, enter a DOI and click &amp;quot;Submit&amp;quot; to add a new paper. You can also use the Batch Import DOI function to add multiple papers at once.&lt;/p>&lt;p>(2) For papers not yet in the Zotero library, presenters can enter the DOI, presenter name, and report date in the Assigned section. The paper will move to Assigned automatically.&lt;/p>&lt;h5>3. Undo Actions&lt;/h5>&lt;p>Claimed papers can be &amp;quot;Undo claim&amp;quot; to return to Unread. Newly added papers can be &amp;quot;Undo&amp;quot; to delete from the Zotero library.&lt;/p>',
confirmTitle: 'Confirm Submission',
confirmOk: 'Confirm',
confirmCancel: 'Cancel',
batchTitle: 'Batch Import DOIs',
batchHint: 'One DOI per line, or separate with semicolons, commas, or spaces, e.g.: 10.1234/abc ; 10.5678/def',
batchSubmit: 'Submit',
batchCancel: 'Cancel',
batchAdd: 'Batch Import',
viewSource: 'View source',
claimBtn: 'Claim',
undoBtn: 'Undo claim',
deleteBtn: 'Undo',
claimTitle: 'Paper Claim',
claimPaper: 'Paper to claim:',
inputName: 'Enter presenter name (e.g. San Zhang, first name first, capitalized):',
inputDate: 'Enter report date (YYYY-MM-DD):',
invalidDate: 'Enter a valid date in YYYY-MM-DD format.',
claimCancel: 'Cancelled.',
claimOk: 'Claim saved.',
undoOk: 'Reverted.',
undoConfirm: 'Undo the current claim?',
deleteConfirm: 'Undo this uploaded paper? This will delete the item from the Zotero group.',
uploadTitleToRead: 'Add new papers to Zotero library',
uploadTitleClaimed: 'Add new papers to Zotero library',
uploadDoiLabel: 'DOI (required, e.g. 10.1016/...)',
uploadNameLabel: 'Presenter name (e.g. San Zhang):',
uploadDateLabel: 'Report date',
uploadSubmit: 'Submit',
uploadSubmitting: 'Submitting...',
uploadSuccess: 'Submitted. The paper has been added to the Zotero group.',
uploadErrorDoi: 'Please enter a valid DOI starting with 10.',
uploadErrorName: 'Please enter presenter name.',
uploadErrorDate: 'Please enter a valid report date.',
saveError: 'Failed: ',
badgeExternal: 'External',
badgePassed: 'Passed',
badgeClaimed: 'Assigned',
badgeReported: 'Reported',
claimantLabel: 'Presenter',
dateLabel: 'Report date',
loadFailed: 'Failed to load literature data.',
untitled: 'Untitled',
categoryLabels: { '\u5DF2\u6C47\u62A5': 'Reported', '\u5DF2\u8BA4\u9886': 'Assigned', '\u5F85\u9605\u8BFB': 'Unread' }
}
};
var t = i18n[lang] || i18n.zh;
filterLabel.textContent = t.filterLabel;
filterInput.placeholder = t.filterPlaceholder;
filterClear.textContent = t.filterClear;
guideBtn.textContent = t.guideBtn;
loadingEl.textContent = t.loading;
guideTitle.textContent = t.guideTitle;
guideBody.innerHTML = t.guideContent;
confirmTitle.textContent = t.confirmTitle;
confirmCancel.textContent = t.confirmCancel;
confirmOk.textContent = t.confirmOk;
batchTitle.textContent = t.batchTitle;
batchInput.placeholder = '10.1234/abc\n10.5678/def';
batchHint.textContent = t.batchHint;
batchCancel.textContent = t.batchCancel;
batchSubmitBtn.textContent = t.batchSubmit;
guideBtn.addEventListener('click', function () { guideOverlay.style.display = 'flex'; });
guideClose.addEventListener('click', function () { guideOverlay.style.display = 'none'; });
guideOverlay.addEventListener('click', function (e) { if (e.target === guideOverlay) guideOverlay.style.display = 'none'; });
function stripHtml(str) { return String(str || '').replace(/&lt;[^>]*>/g, '').trim(); }
function normalizeText(str) { return String(str || '').toLowerCase(); }
function sortByTitle(papers) { return papers.slice().sort(function (a, b) { return stripHtml(a.title).localeCompare(stripHtml(b.title), 'en', { sensitivity: 'base' }); }); }
function isDatePassed(dateStr) { if (!dateStr) return false; var today = new Date(); today.setHours(0,0,0,0); var current = new Date(dateStr); if (isNaN(current.getTime())) return false; current.setHours(0,0,0,0); return current &lt; today; }
function isValidDate(dateStr) { return /^\d{4}-\d{2}-\d{2}$/.test(String(dateStr || '').trim()); }
function formatAuthors(creators) { if (!creators || !creators.length) return ''; var names = creators.map(function (c) { if (c.name) return c.name; return [(c.firstName||'').trim(), (c.lastName||'').trim()].filter(Boolean).join(' '); }).filter(Boolean); return names.length > 3 ? names.slice(0,3).join(', ') + ', et al.' : names.join(', '); }
function normalizeTag(tag) { return typeof tag === 'string' ? tag : (tag &amp;&amp; tag.tag) ? tag.tag : ''; }
function getCategoryLabel(category) { return (t.categoryLabels &amp;&amp; t.categoryLabels[category]) || category; }
function parseEmbeddedData() { if (!dataNode) return {}; try { var p = JSON.parse(dataNode.textContent || '{}'); if (typeof p === 'string') p = JSON.parse(p); return p &amp;&amp; typeof p === 'object' ? p : {}; } catch (e) { return {}; } }
function parseRemoteData(payload) { if (!payload || typeof payload !== 'object') return {}; if (payload.data &amp;&amp; typeof payload.data === 'object') return payload.data; return payload; }
function enrichPaper(paper) { var tags = Array.isArray(paper.tags) ? paper.tags : []; var e = Object.assign({}, paper, { claimant: '', reportDate: '', selfUploaded: false, claimedFromZotero: false }); tags.forEach(function (tag) { var v = normalizeTag(tag); if (!v) return; if (v.indexOf('claimant:') === 0) e.claimant = v.substring('claimant:'.length).trim(); if (v.indexOf('report-date:') === 0) e.reportDate = v.substring('report-date:'.length).trim(); if (v === 'external-claim') e.selfUploaded = true; }); e.claimedFromZotero = !!(e.claimant || e.reportDate); e.searchText = normalizeText([stripHtml(e.title), formatAuthors(e.creators), e.publicationTitle, e.doi, e.abstract, e.claimant, e.reportDate, e.url].join(' ')); return e; }
function apiPost(path, body) { return fetch(path, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }).then(function (r) { return r.text().then(function (text) { var t2 = (text||'').trim(); if (!t2) return { success: false, error: 'Empty response', status: r.status, detail: '' }; try { var p = JSON.parse(t2); if (p &amp;&amp; typeof p === 'object' &amp;&amp; !p.status) p.status = r.status; return p; } catch(e) { return { success: false, error: 'Non-JSON', status: r.status, detail: t2.slice(0,300) }; } }); }); }
function apiGet(path) { var s = path.indexOf('?')===-1?'?':'&amp;'; return fetch(path+s+'_ts='+Date.now(), { method:'GET', cache:'no-store', headers:{'Cache-Control':'no-cache'} }).then(function (r) { return r.text().then(function (text) { var t2 = (text||'').trim(); if (!t2) return { success:false, error:'Empty response', status:r.status, detail:'' }; try { var p = JSON.parse(t2); if (p &amp;&amp; typeof p === 'object' &amp;&amp; !p.status) p.status = r.status; return p; } catch(e) { return { success:false, error:'Non-JSON', status:r.status, detail:t2.slice(0,300) }; } }); }); }
function formatApiError(r) { if (!r) return 'Unknown error'; var p = []; if (r.error) p.push(r.error); if (r.status) p.push('status:'+r.status); if (r.detail) p.push('detail:'+r.detail); return p.length ? p.join(' | ') : 'Unknown error'; }
function normalizeBoardData(raw) { var m = {}; [CATEGORY_REPORTED,CATEGORY_CLAIMED,CATEGORY_TO_READ].forEach(function(c){m[c]=[];}); Object.keys(raw||{}).forEach(function(c){m[c]=sortByTitle((raw[c]||[]).map(enrichPaper));}); return m; }
function setBoardData(raw) { state.data = normalizeBoardData(raw); var cats = Object.keys(state.data); if (!state.activeCategory || cats.indexOf(state.activeCategory)===-1) state.activeCategory = cats[0]||null; }
function hydrateData() { setBoardData(parseEmbeddedData()); }
function refreshFromServer(opts) { opts=opts||{}; if(state.isRefreshing) return Promise.resolve(false); state.isRefreshing=true; if(opts.showLoading){loadingEl.style.display='';loadingEl.textContent=t.loading;} return apiGet('/api/zotero-hugo/papers').then(function(r){state.isRefreshing=false;if(opts.showLoading)loadingEl.style.display='none';if(!r.success){if(opts.alertOnError)window.alert(t.loadFailed+' '+formatApiError(r));return false;}setBoardData(parseRemoteData(r));paint();return true;}).catch(function(e){state.isRefreshing=false;if(opts.showLoading)loadingEl.style.display='none';if(opts.alertOnError)window.alert(t.loadFailed+' '+(e&amp;&amp;e.message?e.message:'Unknown error'));return false;}); }
function ensureRefreshTimer() { if (state.refreshTimer) return; state.refreshTimer = window.setInterval(function(){if(document.visibilityState==='hidden')return;refreshFromServer();},30000); }
function upsertPaper(cat,paper){if(!state.data[cat])state.data[cat]=[];state.data[cat]=state.data[cat].filter(function(e){return e.itemKey!==paper.itemKey;});state.data[cat].push(enrichPaper(paper));state.data[cat]=sortByTitle(state.data[cat]);}
function removePaper(key){var rem=null;Object.keys(state.data).forEach(function(c){var n=[];(state.data[c]||[]).forEach(function(p){if(!rem&amp;&amp;p.itemKey===key){rem={category:c,paper:p};return;}n.push(p);});state.data[c]=n;});return rem;}
function claimTags(tags,name,date){var nt=(tags||[]).filter(function(t2){var v=normalizeTag(t2);return !(v.indexOf('claimant:')===0||v.indexOf('report-date:')===0||v==='external-claim');});nt.push({tag:'claimant:'+name});nt.push({tag:'report-date:'+date});return nt;}
function clearClaimTags(tags){return (tags||[]).filter(function(t2){var v=normalizeTag(t2);return v.indexOf('claimant:')!==0&amp;&amp;v.indexOf('report-date:')!==0;});}
function init() {
toolsEl.style.display = 'flex';
loadingEl.style.display = '';
container.style.display = '';
hydrateData();
loadingEl.style.display = 'none';
tabsEl.style.display = 'flex';
paint();
ensureRefreshTimer();
refreshFromServer({ showLoading: true });
}
filterInput.addEventListener('input', function () { state.query = normalizeText(filterInput.value.trim()); paint(); });
filterClear.addEventListener('click', function () { filterInput.value = ''; state.query = ''; paint(); filterInput.focus(); });
init();
function resolveDoi(doi) {
return fetch('https://api.crossref.org/works/' + encodeURIComponent(doi.trim()), {
headers: { 'User-Agent': 'zotero-hugo-pages-function/1.0' }
}).then(function (r) {
if (!r.ok) return null;
return r.json().then(function (d) {
var msg = d.message || {};
var titles = Array.isArray(msg.title) ? msg.title : [];
return { doi: doi.trim(), title: titles.length ? titles[0] : '' };
});
}).catch(function () { return null; });
}
function showConfirm(items, onConfirm) {
confirmList.innerHTML = '';
items.forEach(function (item) {
var div = document.createElement('div');
div.className = 'zotero-confirm-item';
div.innerHTML = '&lt;div class="doi">' + stripHtml(item.doi) + '&lt;/div>&lt;div class="title">' + (stripHtml(item.title) || t.untitled) + '&lt;/div>';
confirmList.appendChild(div);
});
confirmOverlay.style.display = 'flex';
confirmOk.onclick = function () { confirmOverlay.style.display = 'none'; onConfirm(); };
confirmCancel.onclick = function () { confirmOverlay.style.display = 'none'; };
}
function buildUploadForm(category) {
var wrap = document.createElement('div');
wrap.className = 'zotero-upload-form';
var isToRead = category === CATEGORY_TO_READ;
var h4 = document.createElement('h4');
h4.textContent = isToRead ? t.uploadTitleToRead : t.uploadTitleClaimed;
wrap.appendChild(h4);
var doiRow = document.createElement('div');
doiRow.className = 'form-row';
var doiInput = document.createElement('input');
doiInput.type = 'text';
doiInput.placeholder = t.uploadDoiLabel;
doiRow.appendChild(doiInput);
wrap.appendChild(doiRow);
var nameInput, dateInput;
if (!isToRead) {
var nameRow = document.createElement('div');
nameRow.className = 'form-row';
nameInput = document.createElement('input');
nameInput.type = 'text';
nameInput.placeholder = t.uploadNameLabel;
nameRow.appendChild(nameInput);
var dateLabel = document.createElement('span');
dateLabel.className = 'form-label';
dateLabel.textContent = t.uploadDateLabel;
nameRow.appendChild(dateLabel);
dateInput = document.createElement('input');
dateInput.type = 'date';
nameRow.appendChild(dateInput);
wrap.appendChild(nameRow);
}
var errEl = document.createElement('div');
errEl.className = 'form-error';
wrap.appendChild(errEl);
var btnRow = document.createElement('div');
btnRow.className = 'form-row';
btnRow.style.alignItems = 'center';
var submitBtn = document.createElement('button');
submitBtn.type = 'button';
submitBtn.className = 'form-submit';
submitBtn.textContent = t.uploadSubmit;
btnRow.appendChild(submitBtn);
if (isToRead) {
var batchBtn = document.createElement('button');
batchBtn.type = 'button';
batchBtn.className = 'zotero-batch-btn';
batchBtn.textContent = t.batchAdd;
batchBtn.addEventListener('click', function () { openBatchImport(); });
btnRow.appendChild(batchBtn);
}
wrap.appendChild(btnRow);
submitBtn.addEventListener('click', function () {
var doi = doiInput.value.trim();
if (!doi || !/^10\./.test(doi)) { errEl.style.color = '#dc2626'; errEl.textContent = t.uploadErrorDoi; return; }
if (!isToRead) {
var name = nameInput ? nameInput.value.trim() : '';
var date = dateInput ? dateInput.value : '';
if (!name) { errEl.style.color = '#dc2626'; errEl.textContent = t.uploadErrorName; return; }
if (!isValidDate(date)) { errEl.style.color = '#dc2626'; errEl.textContent = t.uploadErrorDate; return; }
}
errEl.textContent = '';
submitBtn.disabled = true;
submitBtn.textContent = t.uploadSubmitting;
resolveDoi(doi).then(function (resolved) {
var title = resolved ? resolved.title : '';
if (!title) title = doi;
showConfirm([{ doi: doi, title: title }], function () {
var payload = { doi: doi, collection: isToRead ? CATEGORY_TO_READ : CATEGORY_CLAIMED };
if (!isToRead) {
payload.name = nameInput.value.trim();
payload.date = dateInput.value;
}
apiPost('/api/zotero-hugo/zotero-add', payload).then(function (result) {
submitBtn.disabled = false;
submitBtn.textContent = t.uploadSubmit;
if (!result.success) { errEl.style.color = '#dc2626'; errEl.textContent = t.saveError + formatApiError(result); return; }
doiInput.value = '';
if (!isToRead) { nameInput.value = ''; dateInput.value = ''; }
var targetCat = isToRead ? CATEGORY_TO_READ : CATEGORY_CLAIMED;
if (result.paper) { upsertPaper(targetCat, result.paper); state.activeCategory = targetCat; paint(); }
refreshFromServer();
errEl.style.color = '#059669';
errEl.textContent = t.uploadSuccess;
setTimeout(function () { errEl.textContent = ''; errEl.style.color = '#dc2626'; }, 3000);
}).catch(function (err) {
submitBtn.disabled = false;
submitBtn.textContent = t.uploadSubmit;
errEl.style.color = '#dc2626';
errEl.textContent = t.saveError + (err &amp;&amp; err.message ? err.message : 'Unknown error');
});
});
}).catch(function () {
submitBtn.disabled = false;
submitBtn.textContent = t.uploadSubmit;
errEl.style.color = '#dc2626';
errEl.textContent = t.saveError + 'DOI resolve failed';
});
});
return wrap;
}
function openBatchImport() {
batchInput.value = '';
batchOverlay.style.display = 'flex';
batchInput.focus();
}
batchCancel.addEventListener('click', function () { batchOverlay.style.display = 'none'; });
batchOverlay.addEventListener('click', function (e) { if (e.target === batchOverlay) batchOverlay.style.display = 'none'; });
batchSubmitBtn.addEventListener('click', function () {
var raw = batchInput.value.trim();
if (!raw) return;
var dois = raw.split(/[\n\r;,\s]+/).map(function (s) { return s.trim(); }).filter(function (s) { return /^10\./.test(s); });
if (!dois.length) return;
batchSubmitBtn.disabled = true;
batchSubmitBtn.textContent = t.uploadSubmitting;
var resolves = dois.map(function (doi) {
return resolveDoi(doi).then(function (r) {
return { doi: doi, title: r ? r.title : '' };
}).catch(function () { return { doi: doi, title: '' }; });
});
Promise.all(resolves).then(function (items) {
batchOverlay.style.display = 'none';
showConfirm(items, function () {
var chain = Promise.resolve();
items.forEach(function (item) {
chain = chain.then(function () {
return apiPost('/api/zotero-hugo/zotero-add', { doi: item.doi, collection: CATEGORY_TO_READ });
});
});
chain.then(function () { refreshFromServer({ showLoading: true }); }).catch(function () { refreshFromServer({ showLoading: true }); });
});
}).catch(function () {
batchSubmitBtn.disabled = false;
batchSubmitBtn.textContent = t.batchSubmit;
});
});
function getVisiblePapers(category) {
var papers = (state.data[category] || []).filter(function (p) { return p.itemType !== 'attachment' &amp;&amp; p.itemType !== 'note'; });
if (!state.query) return papers;
return papers.filter(function (p) { return p.searchText.indexOf(state.query) !== -1; });
}
function paint() {
var categories = Object.keys(state.data);
tabsEl.innerHTML = '';
container.innerHTML = '';
categories.forEach(function (category) {
var total = (state.data[category] || []).filter(function (p) { return p.itemType !== 'attachment' &amp;&amp; p.itemType !== 'note'; }).length;
var visible = getVisiblePapers(category);
var tab = document.createElement('div');
tab.className = 'zotero-tab' + (category === state.activeCategory ? ' active' : '');
var label = getCategoryLabel(category);
tab.textContent = state.query ? (label + ' (' + visible.length + '/' + total + ')') : (label + ' (' + total + ')');
tab.addEventListener('click', function () { state.activeCategory = category; paint(); });
tabsEl.appendChild(tab);
var panel = document.createElement('div');
panel.className = 'zotero-content' + (category === state.activeCategory ? ' active' : '');
if (category === CATEGORY_TO_READ || category === CATEGORY_CLAIMED) {
panel.appendChild(buildUploadForm(category));
}
if (!visible.length) {
var empty = document.createElement('div');
empty.className = 'zotero-empty';
empty.textContent = t.empty;
panel.appendChild(empty);
} else {
visible.forEach(function (paper, index) {
panel.appendChild(buildCard(paper, category, index + 1, !!state.query));
});
}
container.appendChild(panel);
});
}
function buildCard(paper, category, paperIndex, highlight) {
var card = document.createElement('div');
card.className = 'paper-card' + (highlight ? ' paper-match' : '');
var titleRow = document.createElement('div');
titleRow.className = 'paper-title';
var toggle = document.createElement('span');
toggle.className = 'paper-toggle';
toggle.textContent = paper.abstract ? '\u25b8' : '';
titleRow.appendChild(toggle);
var indexSpan = document.createElement('span');
indexSpan.textContent = paperIndex + '. ';
indexSpan.style.color = '#6b7280';
indexSpan.style.fontWeight = '600';
titleRow.appendChild(indexSpan);
var titleSpan = document.createElement('span');
titleSpan.textContent = stripHtml(paper.title) || t.untitled;
titleRow.appendChild(titleSpan);
card.appendChild(titleRow);
var badgesRow = document.createElement('div');
badgesRow.className = 'paper-badges';
var hasBadge = false;
if (paper.selfUploaded) { var eb = document.createElement('span'); eb.className = 'paper-badge paper-badge-external'; eb.textContent = t.badgeExternal; badgesRow.appendChild(eb); hasBadge = true; }
if (paper.claimedFromZotero) { var cb = document.createElement('span'); cb.className = 'paper-badge paper-badge-claimed'; cb.textContent = category === CATEGORY_REPORTED ? t.badgeReported : t.badgeClaimed; badgesRow.appendChild(cb); hasBadge = true; }
if (category !== CATEGORY_REPORTED &amp;&amp; paper.reportDate &amp;&amp; isDatePassed(paper.reportDate)) { var pb = document.createElement('span'); pb.className = 'paper-badge paper-badge-passed'; pb.textContent = t.badgePassed; badgesRow.appendChild(pb); hasBadge = true; }
if (hasBadge) card.appendChild(badgesRow);
var authors = formatAuthors(paper.creators);
if (authors) { var ae = document.createElement('div'); ae.className = 'paper-authors'; ae.textContent = authors; card.appendChild(ae); }
var meta = document.createElement('div');
meta.className = 'paper-meta';
var metaParts = [];
var yearMatch = String(paper.year || '').match(/(\d{4})/);
if (yearMatch) metaParts.push(yearMatch[1]);
if (paper.publicationTitle) metaParts.push(paper.publicationTitle);
if (paper.doi) metaParts.push('DOI: ' + paper.doi);
meta.textContent = metaParts.join(' | ');
if (paper.url) { var sl = document.createElement('a'); sl.href = paper.url; sl.target = '_blank'; sl.rel = 'noopener'; sl.textContent = t.viewSource; meta.appendChild(sl); }
card.appendChild(meta);
if (paper.claimant || paper.reportDate) {
var cm = document.createElement('div');
cm.className = 'paper-claim-meta';
if (paper.claimant) { var cc = document.createElement('span'); cc.className = 'paper-chip'; cc.textContent = t.claimantLabel + ': ' + paper.claimant; cm.appendChild(cc); }
if (paper.reportDate) { var dc = document.createElement('span'); dc.className = 'paper-chip'; dc.textContent = t.dateLabel + ': ' + paper.reportDate; cm.appendChild(dc); }
card.appendChild(cm);
}
if (paper.abstract) {
var ab = document.createElement('div');
ab.className = 'paper-abstract';
ab.textContent = paper.abstract;
card.appendChild(ab);
titleRow.classList.add('paper-expandable');
titleRow.addEventListener('click', function () { var sh = ab.style.display === 'block'; ab.style.display = sh ? 'none' : 'block'; toggle.classList.toggle('expanded', !sh); });
}
var actionRow = document.createElement('div');
actionRow.className = 'paper-claim';
var hasActions = false;
if (category === claimCat &amp;&amp; !paper.claimedFromZotero &amp;&amp; !paper.selfUploaded) {
var claimBtn = document.createElement('button');
claimBtn.type = 'button';
claimBtn.className = 'zotero-claim-btn';
claimBtn.textContent = t.claimBtn;
claimBtn.addEventListener('click', function () { doClaim(paper); });
actionRow.appendChild(claimBtn);
hasActions = true;
}
if (category !== CATEGORY_REPORTED &amp;&amp; (paper.claimedFromZotero || paper.selfUploaded)) {
var ci = document.createElement('span');
ci.className = 'zotero-claim-info';
ci.textContent = (paper.selfUploaded &amp;&amp; !paper.claimedFromZotero) ? t.badgeExternal : t.badgeClaimed;
actionRow.appendChild(ci);
var ub = document.createElement('button');
ub.type = 'button';
ub.className = paper.selfUploaded ? 'zotero-delete-btn' : 'zotero-undo-btn';
ub.textContent = paper.selfUploaded ? t.deleteBtn : t.undoBtn;
ub.addEventListener('click', function () { undoClaim(paper, category); });
actionRow.appendChild(ub);
hasActions = true;
}
if (hasActions) card.appendChild(actionRow);
return card;
}
function doClaim(paper) {
var title = stripHtml(paper.title) || '';
var name = window.prompt(t.claimTitle + '\n\n' + t.claimPaper + '\n' + title.substring(0, 120) + '\n\n' + t.inputName);
if (!name || !name.trim()) { window.alert(t.claimCancel); return; }
var date = window.prompt(t.inputDate);
if (!date || !date.trim()) { window.alert(t.claimCancel); return; }
if (!isValidDate(date.trim())) { window.alert(t.invalidDate); return; }
apiPost('/api/zotero-hugo/zotero-claim', { action: 'claim', itemKey: paper.itemKey, name: name.trim(), date: date.trim() }).then(function (result) {
if (!result.success) { window.alert(t.saveError + formatApiError(result)); return; }
removePaper(paper.itemKey);
upsertPaper(CATEGORY_CLAIMED, Object.assign({}, paper, { tags: claimTags(paper.tags, name.trim(), date.trim()) }));
state.activeCategory = CATEGORY_CLAIMED;
paint();
refreshFromServer();
window.alert(t.claimOk);
}).catch(function (err) { window.alert(t.saveError + (err &amp;&amp; err.message ? err.message : 'Unknown error')); });
}
function undoClaim(paper, category) {
var treatAsExternalDelete = !!paper.selfUploaded;
var confirmed = window.confirm(treatAsExternalDelete ? t.deleteConfirm : t.undoConfirm);
if (!confirmed) return;
apiPost('/api/zotero-hugo/zotero-claim', { action: 'undo', itemKey: paper.itemKey, external: treatAsExternalDelete }).then(function (result) {
if (!result.success) { window.alert(t.saveError + formatApiError(result)); return; }
removePaper(paper.itemKey);
if (!treatAsExternalDelete) { upsertPaper(CATEGORY_TO_READ, Object.assign({}, paper, { tags: clearClaimTags(paper.tags) })); state.activeCategory = CATEGORY_TO_READ; }
paint();
refreshFromServer();
window.alert(t.undoOk);
}).catch(function (err) { window.alert(t.saveError + (err &amp;&amp; err.message ? err.message : 'Unknown error')); });
}
})();
&lt;/script></description></item><item><title>Lab NAS: Access and Usage Guide</title><link>https://xulab-zotero-test.pages.dev/en/post/lab-nas-guide/</link><pubDate>Sun, 07 Jan 2024 00:00:00 +0000</pubDate><guid>https://xulab-zotero-test.pages.dev/en/post/lab-nas-guide/</guid><description>&lt;h1 id="nas的功能概览">Nas的功能概览&lt;/h1>
&lt;h2 id="目前nas主机校内访问地址">目前NAS主机校内访问地址&lt;/h2>
&lt;p>219.220.17.76（已经弃用）&lt;/p>
&lt;p>&lt;strong>10.160.16.1&lt;/strong>&lt;/p>
&lt;h1 id="下载实验室的文件">&lt;strong>下载实验室的文件&lt;/strong>&lt;/h1>
&lt;h3 id="1-校内访问采用ftp协议连接具体操作如下">1. &lt;strong>校内访问，采用FTP协议连接，具体操作如下：&lt;/strong>&lt;/h3>
&lt;ul>
&lt;li>Windows系统需要打开文件管理器（随便打开一个文件夹）, 在地址栏目中输入 \\10.160.16.1&lt;/li>
&lt;li>Mac系统服务器地址栏：smb://10.160.16.1&lt;/li>
&lt;li>实验室账号用户：登录，填入账号名和密码，可以下载和上传，删除文件&lt;/li>
&lt;li>实验室的相关文件路径：web/lab-禁止外传&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>windows访问流程&lt;/strong>&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="图片1" srcset="
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%871_hu_2fe84e1fc7d4e982.webp 400w,
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%871_hu_94fc3b3972478bd7.webp 760w,
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%871_hu_df9b151bad179b8b.webp 1200w"
src="https://xulab-zotero-test.pages.dev/en/post/lab-nas-guide/%E5%9B%BE%E7%89%871_hu_2fe84e1fc7d4e982.webp"
width="760"
height="263"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>&lt;strong>Mac访问流程&lt;/strong>&lt;/p>
&lt;img src="图片1-1.jpeg" alt="图片1-1" style="zoom:25%;" />
&lt;img src="图片1-2.jpeg" alt="图片1-2" style="zoom:25%;" />
&lt;h3 id="2-校外访问请访问以下链接">2. 校外访问，请访问以下链接：&lt;/h3>
&lt;ul>
&lt;li>
&lt;p>网址链接：https://gofile.me/7zLiM/Cz2Sqe3IN&lt;/p>
&lt;/li>
&lt;li>
&lt;p>访问密码：xulab&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>下载速度比较慢：200k/s左右，仅提供下载权限&lt;/p>
&lt;p>如果要上传文件或者下载自己的文件，请点击右上角登录，进入管理界面&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="图片2" srcset="
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%872_hu_8136170c922d5c04.webp 400w,
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%872_hu_66ef212e5371edaf.webp 760w,
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%872_hu_b2a2f585a5dec728.webp 1200w"
src="https://xulab-zotero-test.pages.dev/en/post/lab-nas-guide/%E5%9B%BE%E7%89%872_hu_8136170c922d5c04.webp"
width="760"
height="266"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h1 id="校外连接校内服务器">校外连接校内服务器&lt;/h1>
&lt;p>&lt;strong>IP地址：ad322hs0577.vicp.fun 端口：24467（流量1G/月，仅用于ssh，切勿传文件）&lt;/strong>&lt;/p>
&lt;p>（通过贝锐花生壳平台做的内网穿透，可以通过外网访问内网的nas）&lt;/p>
&lt;p>&lt;strong>再通过命令：ssh -p 8088 &lt;a href="mailto:chenjiongjin@222.204.6.66">chenjiongjin@222.204.6.66&lt;/a> ，访问服务器&lt;/strong>&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="图片3" srcset="
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%873_hu_f1e35ae90dd29a5c.webp 400w,
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%873_hu_9f48a03a229a74e4.webp 760w,
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%873_hu_541cb9ce486d87bc.webp 1200w"
src="https://xulab-zotero-test.pages.dev/en/post/lab-nas-guide/%E5%9B%BE%E7%89%873_hu_f1e35ae90dd29a5c.webp"
width="752"
height="449"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>网络通路的逻辑图：&lt;/p>
&lt;p>本地主机-&amp;gt;贝锐服务器（ad322hs0577.vicp.fun:24467）-&amp;gt;nas主机（219.220.17.76:22）-&amp;gt;前湖服务器(222.204.6.66:8088)&lt;/p>
&lt;h1 id="连接nas设备">&lt;strong>连接NAS设备&lt;/strong>&lt;/h1>
&lt;h2 id="校内访问">校内访问&lt;/h2>
&lt;p>访问链接：&lt;a href="http://quickconnect.cn/labxu666" target="_blank" rel="noopener">10.160.16.1:5004&lt;/a>&lt;/p>
&lt;p>输入账号密码登录&lt;/p>
&lt;h2 id="校外访问">校外访问&lt;/h2>
&lt;p>访问链接：&lt;a href="http://quickconnect.cn/labxu666" target="_blank" rel="noopener">http://QuickConnect.cn/labxu666&lt;/a>&lt;/p>
&lt;p>输入账号密码登录&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="图片4" srcset="
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%874_hu_963b40972c76eb6a.webp 400w,
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%874_hu_803393009e088723.webp 760w,
/en/post/lab-nas-guide/%E5%9B%BE%E7%89%874_hu_e77fef75bf16179f.webp 1200w"
src="https://xulab-zotero-test.pages.dev/en/post/lab-nas-guide/%E5%9B%BE%E7%89%874_hu_963b40972c76eb6a.webp"
width="760"
height="348"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h1 id="用nas上传公共数据库">用NAS上传公共数据库&lt;/h1></description></item><item><title>Bioinformatics Guide for Beginners</title><link>https://xulab-zotero-test.pages.dev/en/post/bioinformatics-starter-guide/</link><pubDate>Sat, 07 Dec 2019 00:00:00 +0000</pubDate><guid>https://xulab-zotero-test.pages.dev/en/post/bioinformatics-starter-guide/</guid><description>&lt;blockquote>
&lt;p>以下为开启生物信息学习的简易入门教程及小贴士，仅供参考。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="linux">LINUX&lt;/h2>
&lt;h3 id="推荐书籍">推荐书籍&lt;/h3>
&lt;p>阅读原则：第一遍阅读快速浏览，熟悉命令行。大概记住常用命令的使用，实际使用时知道应该调用哪个命令。&lt;/p>
&lt;ol>
&lt;li>&lt;a href="http://linuxcommand.org/tlcl.php" target="_blank" rel="noopener">&lt;em>The Linux Command Line&lt;/em> by William Shotts&lt;/a>&lt;/li>
&lt;li>&lt;em>Learn Linux the Hard Way&lt;/em> by Shaw&lt;/li>
&lt;li>&lt;a href="http://cn.linux.vbird.org/" target="_blank" rel="noopener">《鸟哥的 Linux 私房菜》中文教程&lt;/a>&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="python">PYTHON&lt;/h2>
&lt;h3 id="推荐书籍-1">推荐书籍&lt;/h3>
&lt;p>阅读原则：学到“能写 class”的程度即可。&lt;/p>
&lt;ol>
&lt;li>&lt;em>Python Crash Course&lt;/em> —— 适合零基础，内容偏浅&lt;/li>
&lt;li>&lt;em>Learning Python, 5th Edition&lt;/em> by Mark Lutz —— 系统全面（推荐）&lt;/li>
&lt;li>&lt;em>Python Cookbook (3rd Edition)&lt;/em> by O’Reilly —— 不适合初学者&lt;/li>
&lt;li>&lt;em>Fluent Python&lt;/em> —— 进阶必读&lt;/li>
&lt;li>&lt;a href="https://github.com/jackfrued/Python-100-Days" target="_blank" rel="noopener">Python-100-Days 中文实战教程&lt;/a>&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="qiime-2">QIIME 2&lt;/h2>
&lt;p>详细内容请自行浏览 &lt;a href="https://qiime2.org/" target="_blank" rel="noopener">QIIME 2 官网&lt;/a>。&lt;br>
以下经验基于 &lt;strong>2018.11 版&lt;/strong>，如用其他版本请注意对应教程页左侧的版本号。&lt;/p>
&lt;h3 id="安装小贴士">安装小贴士&lt;/h3>
&lt;ul>
&lt;li>Windows 用户请先装虚拟机 → Linux 系统 → 再装 QIIME 2（注意是 &lt;em>qiime2&lt;/em>，不是 &lt;em>qiime&lt;/em>）。&lt;/li>
&lt;li>全程记录版本号与命令行，方便复现。&lt;/li>
&lt;/ul>
&lt;h3 id="必跑教程">必跑教程&lt;/h3>
&lt;p>重点掌握 &lt;strong>“Moving Pictures”&lt;/strong> 教程：&lt;br>
搞清每一步在做什么、输出文件含义、如何查 help。&lt;/p>
&lt;h3 id="artifact-api">Artifact API&lt;/h3>
&lt;p>可在 Jupyter Notebook 内直接调用&lt;br>
&lt;code>qiime2.Artifact.load()&lt;/code> / &lt;code>.view()&lt;/code> 等接口，方便交互分析。&lt;/p>
&lt;hr>
&lt;h3 id="moving-pictures-精要">Moving Pictures 精要&lt;/h3>
&lt;h4 id="1-metadata--mapping-文件">1. Metadata / Mapping 文件&lt;/h4>
&lt;pre>&lt;code>- metadata记录原始数据，样本信息等，metadata需为tsv格式。
- metadata第一列名应为sampleid，注意sampleid列中的样本名不可以含有下划线（deblur DOESN'T support sample IDs with underscores, including the sample IDs in your metadata and sequence files, or your manifest file)
- metadata的要求请参照[Metadata in QIIME 2](https://docs.qiime2.org/2019.10/tutorials/metadata/)
&lt;/code>&lt;/pre>
&lt;ol start="2">
&lt;li>sequence files
&lt;ul>
&lt;li>序列文件通常为fastq/fna格式，less可查看，gz文件用zless查看。&lt;/li>
&lt;li>序列文件是已经去掉了barcode/primer/adaptor的clean data。&lt;/li>
&lt;li>demux后的序列文件通过提供manifest来导入，注意不同日期批次的qiime2在menifast格式上可能存在区别，所以一定要确认你正在使用的qiime2的版本。&lt;/li>
&lt;li>注意:所有的序列都应该测的是同一段区域（起点相同），序列之间才具有可比性，否则序列比对是没有意义的。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>barcode files
&lt;ul>
&lt;li>barcode用来区别该序列来自于哪个样本，类似于商品的条形码。来自同一个样本的序列用相同barcode标记，所以根据barcode可以知道哪条序列属于哪个样本。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>demultiplex
&lt;ul>
&lt;li>根据barcode信息，判断sequence是来自哪个样本，从而得到每个样本含有哪些序列，有多少序列。&lt;/li>
&lt;li>如为反向互补序列，demux 时选择参数 &lt;code>--p-rev-comp-mapping-barcodes&lt;/code>。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>quality control
&lt;ul>
&lt;li>推荐deblur:&lt;a href="http://msystems.asm.org/content/2/2/e00191-16" target="_blank" rel="noopener">deblur&lt;/a>较传统的OTU聚类的方法，可以得到更精确的亚OTUs的信息。该方法是分别对单个样本进行分析，当样本来自不同批次或不同数据集时，该方法同样适用。&lt;/li>
&lt;li>如果input是paired end sequence data，在deblur时实际上只会用到正向序列，而不会用到反向序列。如有需要用到反向序列，可&lt;a href="https://docs.qiime2.org/2019.4/tutorials/read-joining/" target="_blank" rel="noopener">join reads&lt;/a>。&lt;/li>
&lt;li>qiime deblur denoise-16S 需要注意的参数：
(a) &lt;code>--p-no-hashed-feature-ids&lt;/code> 即保留原始序列（ATGC格式）。
(b) &lt;code>--p-min-reads&lt;/code>
(c) 查看deblur.qzv：理论上deblur之后剩下的序列数为(1-error rate)**trim length（其中error rate=0.005）；以100个碱基长度为例，deblur之后剩下的序列&amp;gt;(1-0.005)**100才比较合理&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>generate a tree
&lt;ul>
&lt;li>moving picture中介绍了rooted tree&lt;/li>
&lt;li>其他建树的方法有fragment insertion sepp&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>diversity analysis
&lt;ul>
&lt;li>参数&lt;code>--p-sample-depth&lt;/code>的选择，可参考rarefaction curve，选择曲线上升到平台期为宜。&lt;/li>
&lt;li>diversity的分析前，不要忘记对table做rarefy！rarefaction的意义在于，当抽样深度不同时，rarefaction使不同测序深度间变得有可比性。&lt;/li>
&lt;li>alpha diversity: how many kinds of microbes are there单个样本内含有多少微生物。可从以下几个方面比较：（1）richness 种类（例如2个样本，1号含100种微生物，2号含150种微生物，这里只考虑种类，不考虑数量）；（2）evenness 均匀度（例如2个样本，1号含A3B3C3,2号A1B1C7，字母代表不同的OTU，数字代表个数，那么这个例子中1号OTU分布显然比2号更均匀）。常用计算alpha div的方法有：（1）observed otus (richness) 只计算每个样本中otu的种类；（2）evenness (evenness) 解释见上；（3）shannon (richness + evenness) 既考虑种类又考虑均匀度；（4）simpson (richness + evenness) 同上；（5）faith&amp;rsquo;s phylogenetic distance 除了还考虑种类和均匀度，还考虑进化距离……&lt;/li>
&lt;li>beta diversity: similarity and dissimilarity between two different samples两个样本间的相似性或不同&lt;/li>
&lt;li>在coursera课程&lt;a href="https://www.coursera.org/learn/microbiome" target="_blank" rel="noopener">Gut Check: Exploring Your Microbiome&lt;/a>中，有关于diversity有生动的说明，请自行移步。另外可参考&lt;a href="http://readiab.org/book/0.1.3/3/1#4.1.2" target="_blank" rel="noopener">Studying Microbial Diversity&lt;/a>。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>taxonomy assignment
&lt;ul>
&lt;li>根据实际情况，可选择用pre-trained Naive Bayes classifier ;如不适用，可根据自己的primer来&lt;a href="https://docs.qiime2.org/2019.4/tutorials/feature-classifier/" target="_blank" rel="noopener">train classfier&lt;/a>。&lt;/li>
&lt;li>qiime feature-classifier classify-sklearn &lt;code>--p-read-orientation&lt;/code> [reverse-complement|same]默认是自动检测前100个bases，然后判断是reverse还是same，一般默认参数就行。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>ANCOM：得到差异表达的OTU
&lt;ul>
&lt;li>ancom默认进行比较的两组样本是相互独立的，且仅有少量的（少于25%）的OTUs在两组间发生了改变。如果有大量序列改变，则不适用。&lt;/li>
&lt;li>其他differential abundance计算方法还有q2-aldex2, q2-songbird, q2-conrcob等。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h3 id="importing-data">Importing Data&lt;/h3>
&lt;ul>
&lt;li>tsv, csv, txt文件可转化成&lt;a href="http://biom-format.org/documentation/biom_conversion.html" target="_blank" rel="noopener">The Biological Observation Matrix (BIOM) format&lt;/a>再导入。&lt;/li>
&lt;/ul>
&lt;h3 id="emperor-animation">Emperor Animation&lt;/h3>
&lt;ul>
&lt;li>emperor可实现动画：在&lt;a href="https://view.qiime2.org/" target="_blank" rel="noopener">qiime2 view&lt;/a>中打开emperor.qzv文件，右侧栏选择animation列，选择gradient（时间轴上的分组）和trajectory（样本的分组）category（它们的value必须是分类值，不能是数值）。&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="tips">Tips&lt;/h3>
&lt;ul>
&lt;li>查看tutorial时需注意当前版本，应与安装的版本相对应（tutorial页面最左有版本信息），否则有些代码时可能会出现报错。&lt;/li>
&lt;li>命名不要有空格和中文，不要取模棱两可的名字，时间久了可能自己都不记得这个文件是什么。名字长一点都没关系。&lt;/li>
&lt;li>原则上不产生重复文件，可创建hard/symbolic link。&lt;/li>
&lt;li>不要轻易覆盖raw data。&lt;/li>
&lt;li>碰到解决不了的问题可在qiime2 forum上找是否有同样的问题，通常可以找到。或可以自己在上面提问。&lt;/li>
&lt;li>所有command lines都要做好记录，要知道每一个文件是如何生成的，出现问题的时候能够追根溯源。同时，要记录好qiime2及其他工具的版本信息。&lt;/li>
&lt;li>重要的文本文件用git做version control。&lt;/li>
&lt;li>图片保存格式为pdf或者svg（矢量图）。&lt;/li>
&lt;li>做项目时，一个项目创建一个文件夹，与该项目相关的文件都保存在该目录下。&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="课程推荐">课程推荐&lt;/h2>
&lt;h3 id="data-analysis">Data Analysis&lt;/h3>
&lt;ul>
&lt;li>经过学习以上部分，有了基础概念之后，跟着这个&lt;a href="https://github.com/cuttlefishh/python-for-data-analysis" target="_blank" rel="noopener">网址&lt;/a>进行数据分析课程的学习&lt;/li>
&lt;li>参考用书“Python for Data Analysis”，涉及pandas，numpy，matplotlib，seaborn…&lt;/li>
&lt;/ul>
&lt;h3 id="microbiome">Microbiome&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="https://www.coursera.org/learn/microbiome" target="_blank" rel="noopener">Gut Check: Exploring Your Microbiome&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="阅读推荐">阅读推荐&lt;/h2>
&lt;h3 id="期刊">期刊&lt;/h3>
&lt;p>推荐期刊：&lt;em>Nature&lt;/em>、&lt;em>Science&lt;/em>、&lt;em>Cell&lt;/em>、&lt;em>PNAS&lt;/em>、&lt;em>Nature Communications&lt;/em>、&lt;em>Nature Microbiology&lt;/em>、&lt;em>Microbiome&lt;/em>、&lt;em>Cell Host &amp;amp; Microbes&lt;/em>、&lt;em>ISME Journal&lt;/em>、&lt;em>Gut&lt;/em>、&lt;em>Gastroenterology&lt;/em>、&lt;em>Genome Research&lt;/em>、&lt;em>mBio&lt;/em>、&lt;em>mSystems&lt;/em>&lt;/p>
&lt;h3 id="tips-1">Tips&lt;/h3>
&lt;ul>
&lt;li>看文献时，&lt;strong>Abstract → Figures → Discussion&lt;/strong>&lt;/li>
&lt;li>看文献时也要了解作者，通过作者去了解别人实验室的研究方向，可以学习别人实验上的思路/实验设计/延续性等。&lt;/li>
&lt;li>带着批判性思维阅读&lt;strong>What？Why？How？&lt;/strong> 为什么要做这个实验，数据是否支持结论，统计方法是否正确，你接下来会怎么做等。&lt;/li>
&lt;li>在自己研究方向上进行阅读，形成知识架构。什么是已知的，什么的未知的，提出问题，多思考如何解决问题。&lt;/li>
&lt;li>文献汇报选择与自己研究直接相关的文章，有助于自己文献阅读的连续性。&lt;/li>
&lt;li>实验汇报用1套PPT，每次在之前的基础上积累完善。包括背景介绍，提出问题，如何解决，用什么方法解决，结果，下阶段的计划安排。&lt;/li>
&lt;/ul>
&lt;h3 id="书籍">书籍&lt;/h3>
&lt;ol>
&lt;li>&lt;em>I Contain Multitudes&lt;/em> by Ed Yong&lt;/li>
&lt;li>&lt;em>Missing Microbes&lt;/em> by Martin J. Blaser&lt;/li>
&lt;li>&lt;a href="http://library.open.oregonstate.edu/computationalbiology/" target="_blank" rel="noopener">A Primer for Computational Biology&lt;/a>（免费电子书）&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="其他工具">&lt;strong>其他工具&lt;/strong>&lt;/h1>
&lt;h2 id="calour">calour&lt;/h2>
&lt;ul>
&lt;li>熟悉tutorial&lt;/li>
&lt;li>得到otuTable后，通常会用calour工具进行一些探索性的分析，用calour工具可以非常方便地对data进行filtering。&lt;/li>
&lt;/ul>
&lt;h2 id="matplotlibseaborn">matplotlib/seaborn&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>最常用的画图工具，推荐教程： &lt;a href="https://www.labri.fr/perso/nrougier/teaching/matplotlib/" target="_blank" rel="noopener">matplotlib-tutorial&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://matplotlib.org/gallery/misc/multipage_pdf.html" target="_blank" rel="noopener">mutipage pdf&lt;/a> 可同时保存多张图片&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="jupyter-notebookjupyterlab--ipython">jupyter notebook/jupyterlab &amp;amp; ipython&lt;/h2>
&lt;ul>
&lt;li>Don&amp;rsquo;t forget we can look at what any function does by using %psource&lt;/li>
&lt;li>Don&amp;rsquo;t hardcode。同一套代码写成function后调用。写function注意逻辑性。&lt;/li>
&lt;/ul>
&lt;h2 id="git-commands">git commands&lt;/h2>
&lt;ul>
&lt;li>Github
&lt;a href="https://guides.github.com/activities/hello-world/" target="_blank" rel="noopener">hello world tutorial&lt;/a>
&lt;a href="https://github.com/cuttlefishh/python-for-data-analysis/blob/master/lessons/lesson20.md" target="_blank" rel="noopener">git and github&lt;/a>&lt;/li>
&lt;li>Git commands
&lt;a href="https://www.youtube.com/watch?v=HVsySz-h9r4" target="_blank" rel="noopener">command-line fundamentals&lt;/a>（视频介绍）&lt;/li>
&lt;li>重要的文件用git做version control，尤其是自己写的文本文件。了解简单的git add/commit/pull/push等命令的使用。&lt;/li>
&lt;/ul>
&lt;h2 id="coursera-dl">coursera-dl&lt;/h2>
&lt;ul>
&lt;li>coursera课程可通过coursera-dl命令进行下载，详见&lt;a href="https://github.com/coursera-dl/coursera-dl" target="_blank" rel="noopener">coursera-dl github&lt;/a>。&lt;/li>
&lt;/ul></description></item></channel></rss>