{{ t('build.new') }} {{ t('build.reload') }}

{{ cfg.name }}

{{ t('login.tag') }}
{{ loginErr }}
EN 中文
{{ t('login.foot') }}
{{ titles[page][0] }}
{{ titles[page][1] }}
EN 中文
{{ t('nav.logout') }}
{{ greeting }}, {{ user.name }}
{{ today }} · {{ statsText }} ⚙ {{ t('wg.choose') }}

{{ t('wg.tasks') }}

{{ t('wg.open') }}
{{ widgets.data.tasks.assigned }}{{ t('wg.inProgress') }}
{{ widgets.data.tasks.pool }}{{ t('wg.unassigned') }}
{{ widgets.data.tasks.dueSoon }}{{ t('wg.dueSoon') }}
{{ widgets.data.tasks.overdue }}{{ t('wg.overdue') }}
{{ widgets.data.tasks.done }} / {{ totalTasks }} {{ t('wg.done') }}

{{ t('wg.timeline') }}

{{ e.title }}
{{ e.kind === 'task' ? t('wg.task') : t('wg.approval') }} · {{ e.detail }} · {{ shortDate(e.ts) }}
—

{{ t('wg.mail') }}

{{ t('wg.open') }}
{{ widgets.data.mail.unread === null ? '—' : widgets.data.mail.unread }}
{{ mailUnit }}

{{ t('wg.meetings') }}

{{ t('wg.open') }}
{{ m.title }}
{{ shortDate(m.starts_at) }} · {{ m.room }}
{{ t('wg.noMeeting') }}

{{ t('wg.groupFiles') }} · {{ widgets.data.groupFiles.dept }}

{{ t('wg.open') }}
{{ widgets.data.groupFiles.count }}
{{ t('wg.newIn7d') }}
· {{ f.name }}

{{ t('wg.users') }}

{{ t('wg.open') }}
{{ widgets.admin.users.total }}{{ t('wg.totalUsers') }}
{{ widgets.admin.users.yesterday }}{{ t('wg.yesterday') }}
{{ widgets.admin.users.active7 }}{{ t('wg.active7') }}
{{ widgets.admin.users.never }}{{ t('wg.never') }}

{{ t('wg.system') }}

{{ t('dash.refresh') }}
{{ t('wg.cpu') }}
{{ pct(widgets.admin.system.now.cpu) }}%
{{ t('wg.ram') }}
{{ pct(widgets.admin.system.now.mem) }}%
{{ t('wg.disk') }}
{{ pct(widgets.admin.system.disk.percent) }}%
{{ t('wg.window') }}{{ t('wg.cpu') }}{{ t('wg.ram') }}
1H{{ pct(widgets.admin.system.h1.cpu) }}%{{ pct(widgets.admin.system.h1.mem) }}%
4H{{ pct(widgets.admin.system.h4.cpu) }}%{{ pct(widgets.admin.system.h4.mem) }}%
24H{{ pct(widgets.admin.system.h24.cpu) }}%{{ pct(widgets.admin.system.h24.mem) }}%

{{ t('apv.pending') }}

{{ apvPending.length }}
{{ a.title }}
{{ a.requester }} · {{ shortDate(a.created_at) }}
{{ a.file_name }}

{{ t('dash.systemStatus') }}

{{ t('dash.fileEngine') }}
Nextcloud
{{ health.nextcloud ? t('dash.normal') : t('dash.abnormal') }}
{{ t('dash.mailAccess') }}
{{ mailAccounts.length ? (mailAccounts.length + ' ' + t('dash.accounts')) : t('dash.notConfigured') }}
{{ mailAccounts.length ? t('dash.normal') : t('dash.notConfigured') }}
{{ t('dash.meetingService') }}
LiveKit
{{ lkJoined ? t('dash.inMeeting') : t('dash.ready') }}

{{ t('mail.setupTitle') }}

{{ t('mail.noAccount') }}

{{ t('mail.folders') }} ⚙
{{ folderLabel(f) }}
{{ a.label }}{{ a.username }}
{{ mailSel.length }} {{ mailLoading ? t('dash.loading') : (mailList.length + ' ' + t('mail.messages')) }} {{ t('mail.refresh') }} + {{ t('mail.compose') }}
{{ m.fromName }} {{ shortDate(m.date) }}
{{ m.subject }}
{{ t('mail.empty') }}
{{ t('mail.pickOne') }}
{{ t('mail.dblHint') }}

{{ mailCur.subject }}

{{ mailCur.fromName }} <{{ mailCur.fromAddr }}>
{{ shortDate(mailCur.date) }} · {{ t('mail.recipients') }} {{ mailCur.to }}
{{ mailCur.body || t('mail.noBody') }}
{{ a.filename }} {{ formatSize(a.size) }}
{{ wsCollapsed.mine ? '▸' : '▾' }} {{ t('ws.myFolder') }} {{ personalFiles.length }}
{{ wsCollapsed.group ? '▸' : '▾' }} {{ t('ws.groupFolder') }} · {{ dept }} {{ groupFiles.length }}
{{ wsCollapsed.other ? '▸' : '▾' }} {{ t('ws.other') }}{{ otherFolders.length }}
{{ t('ws.tip') }}
{{ t('ws.tipText') }}

{{ t('ws.pool') }}

{{ t('ws.dragToMember') }}
{{ t2.title }}
{{ t2.content }}
{{ t2.start_date }} → {{ t2.due_date }} {{ t('ws.overdue') }} {{ daysLeft(t2) }} {{ t('ws.daysLeft') }}
{{ a.name }}
✎
{{ t('ws.allAssigned') }}

{{ t('ws.members') }}

{{ t('ws.dropOnPerson') }}
{{ initialsOf(m.name) }}
{{ m.name }}
{{ pendingCount(m.name) }} {{ t('ws.items') }}

{{ t('ws.pendingTitle') }}

{{ pending.length ? (pending.length + ' ' + t('ws.items')) : t('ws.pendingHint') }}
{{ p.task }}→ {{ p.names.join(', ') }} ×
{{ t('ws.noPending') }}
{{ submitInfo }}

{{ t('apv.pending') }}

{{ apvPending.length }}
{{ a.title }}
{{ a.requester }} · {{ shortDate(a.created_at) }}
{{ a.file_name }}

{{ t('apv.mine') }}

{{ apvMine.length }}
{{ a.title }}
{{ a.approver }} · {{ shortDate(a.decided_at || a.created_at) }}
{{ a.file_name }}
🔏 {{ t('apv.stampedCopy') }}
{{ a.status === 'approved' ? t('pv.approved') : a.status === 'rejected' ? t('pv.rejected') : t('apv.pending') }}

{{ t('ws.assigned') }}

{{ assigned.length }}
{{ a.title }}
{{ a.content }}
{{ asgNames(a) }} · {{ a.due_date || (a.note || t('ws.inProgress')) }} · {{ t('ws.overdue') }} · {{ daysLeft(a) }} {{ t('ws.daysLeft') }}
{{ f.name }}
{{ t('ws.notified') }} {{ t('ws.inProgress') }} ✎
{{ t('ws.noAssigned') }}

{{ t('meet.title') }}

{{ t('meet.hint') }}

{{ lkMsg }}
{{ t('meet.devices') }} ⟳ {{ t('dash.refresh') }}
{{ t('meet.devHint') }}

{{ t('meet.schedule') }}

{{ t('meet.upcoming') }}

{{ m.title }}
{{ shortDate(m.starts_at) }} · {{ m.room }}
{{ t('meet.noUpcoming') }}
{{ t('meet.inMeeting') }} · {{ lkRoom }} · {{ lkCount }} {{ t('meet.people') }}
{{ t('wb.pen') }} {{ t('wb.size') }}
{{ wb.bg.name }}×
{{ t('wb.dropHint') }}
{{ calTitle }}
{{ t('cal.meeting') }} {{ t('cal.taskDue') }}
{{ w }}
{{ c.day }}
{{ e.time }} {{ e.title }}
{{ t('admin.users') }}
{{ t('adm.groups') }}
{{ t('admin.identity') }}
{{ t('adm.federation') }}
{{ t('admin.mail') }}
{{ t('admin.params') }}
{{ t('adm.chatLogs') }}

{{ t('admin.newUser') }}

✓ {{ t('adm.created') }}
{{ t('adm.credentials') }}
{{ t('login.account') }}{{ admCreated.id }}
{{ t('login.password') }}{{ admCreated.password }}
{{ t('admin.email') }}{{ admCreated.email }}
{{ t('admin.id') }}{{ t('admin.name') }} {{ t('admin.quota') }}{{ t('apv.manager') }}{{ t('admin.lastLogin') }}
{{ u.id }}{{ t('admin.you') }} {{ u.name }} {{ u.quota ? formatSize(u.quota) : '—' }} {{ u.manager || '—' }} {{ u.lastLogin ? shortDate(new Date(u.lastLogin).toISOString()) : t('admin.never') }} {{ u.enabled ? t('admin.enabled') : t('admin.disabled') }}

{{ t('adm.newGroup') }}

{{ t('adm.groupId') }}{{ t('adm.members') }}
{{ g.id }} {{ g.members }} system
{{ t('dash.loading') }}

{{ t('admin.identityMode') }}

{{ identityHint }}

{{ t('adm.emailAsUserHint') }}

LDAP / Active Directory

{{ t('adm.fedTopology') }}

{{ t('adm.fedHint') }}

{{ t('adm.fedHomeHint') }}

{{ t('adm.fedLinks') }}

{{ t('adm.fedProbeAll') }}

{{ t('adm.fedLinkHint') }}

{{ t('adm.fedLink') }}{{ t('adm.fedEnabled') }} {{ t('adm.fedAuthKey') }}{{ t('adm.fedState') }}
{{ fedName(l.a) }} ↔ {{ fedName(l.b) }} {{ fedState[linkOther(l)].ok ? (fedState[linkOther(l)].via === 'lan' ? 'IPSec' : 'WAN') : fedState[linkOther(l)].reason }} — —

{{ t('adm.fedLinkKeyHint') }}

{{ t('adm.fedCompanies') }}

{{ t('adm.fedCompany') }}{{ t('adm.fedDomain') }} IPSec{{ t('adm.fedWan') }} {{ t('adm.fedState') }}
{{ c.name }} home {{ c.domain || '—' }} local {{ fedState[c.code].ok ? (fedState[c.code].via === 'lan' ? 'IPSec' : 'WAN') : fedState[c.code].reason }} —

{{ t('adm.fedFileHint') }}

{{ t('admin.mail') }}

{{ t('adm.mailImapOnly') }}

{{ t('admin.params') }}

{{ t('adm.chatLogs') }}

{{ t('dash.refresh') }}
Conversation{{ t('adm.messages') }}Last
{{ c.id }} {{ c.total }} {{ shortDate(c.last_at) }}
{{ t('adm.noChats') }}
{{ admMsg }}
{{ t('dash.loading') }}
{{ chatUnread }}
‹ {{ conv ? peerName : t('chat.title') }} ×
{{ t('chat.dm') }}
{{ t('chat.groups') }}
{{ t('nav.meeting') }}
#
{{ g.title }}
{{ g.members }} {{ t('chat.members') }} · {{ g.last_body }}
›
{{ t('chat.noGroups') }}
{{ t('chat.meetHint') }}
{{ m.me ? (lang === 'zh' ? '我' : 'Me') : m.who }}
{{ m.text }}
{{ m.file }}
{{ t('chat.noMessages') }}
{{ t('mail.compose') }}×
{{ t('chat.pickFile') }}×
{{ t('chat.personal') }} {{ t('chat.group') }}
{{ f.name }} {{ formatSize(f.size) }}
{{ t('chat.noFiles') }}
{{ t('admin.editUser') }} · {{ admEdit.id }}×
{{ t('apv.decideTitle') }} ×
{{ apvDecide.item && apvDecide.item.title }}
{{ apvDecide.item && apvDecide.item.requester }}

{{ t('apv.commentHint') }}

{{ taskForm.id ? t('ws.editTask') : t('ws.newTask') }} ×
{{ t('ws.attachments') }} {{ taskForm.atts.length }}
{{ a.name }} ×
{{ t('ws.noAtt') }}
{{ t('ws.assignees') }} {{ taskForm.who.length }}
{{ t('chat.noContacts') }}

{{ t('ws.assignHint') }}

{{ t('ws.pickFromFiles') }} ×
—
{{ t('ws.confirmAssign') }} ×

{{ t('ws.confirmAssignHint') }}

{{ p.task }}
→ {{ p.names.join(', ') }}
{{ t('idle.title') }}

{{ idleText }}

{{ idleLeft }}
{{ t('wg.choose') }} ×

{{ t('wg.hint') }}

{{ t('adm.groupEdit') }} · {{ groupEdit.id }} ×
{{ t('adm.inGroup') }} {{ groupEdit.members.length }}
{{ m.name }} ×
{{ t('adm.noMembers') }}
{{ t('adm.addPeople') }} {{ groupEdit.add.length }}
{{ t('adm.allInGroup') }}

{{ t('adm.groupIdHint') }}

{{ t('chat.membersTitle') }} ×
{{ t('chat.inGroup') }} {{ groupMem.list.length }}
{{ m.name }} {{ t('chat.ownerBadge') }} ×
{{ t('chat.addPeople') }} {{ groupMem.add.length }}
{{ t('chat.noContacts') }}

{{ t('chat.onlyOwner') }}

{{ t('chat.newGroup') }} ×
{{ t('chat.selectMembers') }} {{ newGroup.members.length }}
{{ t('chat.noContacts') }}
{{ t('mail.syncFolders') }} ×

{{ t('mail.syncHint') }}

{{ t('dash.loading') }}
{{ t('pwd.title') }}×
{{ t('apv.submit') }} ×
{{ t('chat.personal') }} {{ t('chat.group') }} · {{ dept }}
{{ f.name }} {{ formatSize(f.size) }}
{{ t('chat.noFiles') }}
{{ t('apv.approvers') }} {{ apvChain.length }}
{{ i + 1 }} {{ userName(u) }} ×
{{ t('apv.noApprover') }}

{{ t('apv.chainHint') }}

{{ t('apv.noManager') }}
{{ t('apv.cc') }} {{ apvCc.length }}
CC {{ userName(u) }} ×
{{ t('apv.noCc') }}

{{ t('apv.ccHint') }}

{{ t('apv.idleTitle') }} ×

{{ t('apv.idleBody').replace('{h}', idleAsk.hours).replace('{m}', idleAsk.manager).replace('{s}', idleAsk.secondaryName) }}

{{ admChatConv.id }} {{ admChatMsgs.length }} {{ t('adm.messages') }} ×
{{ shortDate(m.created_at) }} {{ m.sender_name || m.sender }} {{ m.body || (m.attachment && m.attachment.name) || '' }}
—
{{ preview.name }} {{ formatSize(preview.size) }} ×
{{ previewStamp.status === 'approved' ? '✓ ' + t('pv.approved') : '✕ ' + t('pv.rejected') }} · {{ previewStamp.approverName || previewStamp.approver }} · {{ shortDate(previewStamp.decidedAt) }} {{ t('pv.hash') }} {{ (previewStamp.fileHash || '').slice(0, 10) }}… 🔏 {{ previewStamp.sigValid ? t('pv.sigOk') : t('pv.sigBad') }} · {{ previewStamp.sigAlg }} {{ t('pv.sigNone') }}
{{ t('pv.sigAlg') }}{{ previewVerify.signature && previewVerify.signature.alg }}
{{ t('pv.sigApprover') }}{{ previewVerify.signature && previewVerify.signature.approver }}
{{ t('pv.sigTime') }}{{ previewVerify.signature ? shortDate(previewVerify.signature.decidedAt) : '' }}
{{ t('pv.sigKey') }}{{ previewVerify.signature && previewVerify.signature.keyFp }}
{{ t('pv.sigPayload') }}{{ previewVerify.signature && (previewVerify.signature.payloadHash || '').slice(0,16) }}…
{{ t('pv.sigFile') }} {{ previewVerify.fileIntact === null ? '—' : previewVerify.fileIntact ? t('pv.sigFileOk') : t('pv.sigFileBad') }}
{{ t('pv.sigStamp') }} {{ previewVerify.stamped.intact === null ? t('pv.sigStampUnbound') : previewVerify.stamped.intact ? t('pv.sigFileOk') : t('pv.sigFileBad') }}
{{ t('pv.sigTrail') }} {{ previewVerify.trail.map(x => (x.stage + '·' + userName(x.approver) + (x.valid ? ' ✓' : ' ✕'))).join(' ') }}
⚠ {{ t('pv.tampered') }}
{{ previewStamp.status === 'approved' ? t('pv.approved') : t('pv.rejected') }}
Loading…
{{ preview.text }}
{{ t('pv.sheet') }}: {{ preview.sheetName }} · {{ preview.sheetCount }} {{ t('pv.ofSheets') }}

{{ t('pv.officeHint') }}

{{ browse.name }} ×
{{ f.name }} {{ formatSize(f.size) }}
{{ t('chat.noFiles') }}

{{ t('ws.archiveHint') }}

{{ t('meet.testTitle') }} ×

{{ t('meet.testHint') }}

{{ meetTestMsg }}

{{ t('meet.edit') }} ×
{{ toast }}