a642bf16a2
design/ 同步自最新设计导出,新增 ui_kits/tablet/ 平板分栏布局;todo/ 录入 18 个并行实施任务。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
241 lines
14 KiB
JavaScript
241 lines
14 KiB
JavaScript
/* site.js — 穿山甲 VPN 官网 · i18n + 交互 */
|
||
(function () {
|
||
// ---------- i18n ----------
|
||
const I18N = {
|
||
'ann.txt': ['新用户注册即享 7 天免费试用', 'New users get a 7-day free trial'],
|
||
'ann.cta': ['立即注册 →', 'Sign up →'],
|
||
|
||
'su.ph': ['输入邮箱,免费注册', 'Enter email to sign up free'],
|
||
'su.btn': ['免费注册', 'Sign up free'],
|
||
'su.ok': ['验证码已发送!下载 App 并用同一邮箱继续完成注册。', 'Code sent! Download the app and continue with the same email.'],
|
||
'su.hint': ['免费注册 · 无需付款 · 7 天免费试用', 'Free to join · no payment · 7-day free trial'],
|
||
'su.dl': ['或直接下载 App', 'or just download the app'],
|
||
|
||
'why.eyebrow': ['免费注册', 'Sign up'],
|
||
'why.h': ['注册一次,处处可用', 'One account, everywhere'],
|
||
'why.sub': ['一个邮箱就能开始。注册免费,不需要任何付款信息。', 'All you need is an email. Free to join — no payment details, ever.'],
|
||
'why.1t': ['7 天免费试用', '7-day free trial'],
|
||
'why.1d': ['新用户注册即享 7 天免费使用,无需任何付款信息。', 'New accounts get 7 days of free, unrestricted use — no payment details.'],
|
||
'why.2t': ['多端同步', 'Multi-device sync'],
|
||
'why.2d': ['手机、平板、电脑共用一个账户,套餐与设置随身走。', 'Phone, tablet and desktop share one account — your plan follows you.'],
|
||
'why.3t': ['无需付款信息', 'No payment details'],
|
||
'why.3d': ['注册只要邮箱。想升级时,再通过外部渠道兑换激活码。', 'Just an email to join. Upgrade later with an activation code.'],
|
||
'why.s1': ['填写邮箱', 'Enter email'],
|
||
'why.s2': ['输入验证码', 'Verify code'],
|
||
'why.s3': ['开始畅连', 'Start connecting'],
|
||
'why.cta': ['立即免费注册', 'Sign up free'],
|
||
|
||
'cta.btn2': ['免费注册', 'Sign up free'],
|
||
|
||
'nav.product': ['产品', 'Product'],
|
||
'nav.pricing': ['定价', 'Pricing'],
|
||
'nav.download': ['下载', 'Download'],
|
||
'nav.docs': ['文档', 'Docs'],
|
||
'nav.blog': ['Blog', 'Blog'],
|
||
'nav.login': ['登录', 'Log in'],
|
||
'nav.get': ['立即下载', 'Get the app'],
|
||
|
||
'hero.eyebrow': ['极速 · 稳定 · 省心', 'Fast · Stable · Effortless'],
|
||
'hero.h1': ['极速畅连,\n网络如丝顺滑', 'Faster, smoother,\neverywhere'],
|
||
'hero.lede': ['轻盈、亲和、即开即用的跨平台网络加速应用。一键连接,智能选线,稳定不掉线。', 'A lightweight, friendly cross-platform network accelerator. One tap, smart routing, rock-solid.'],
|
||
'hero.cta1': ['免费下载', 'Download free'],
|
||
'hero.cta2': ['查看定价', 'See pricing'],
|
||
'hero.t1': ['80+ 全球加速线路', '80+ global routes'],
|
||
'hero.t2': ['严格无日志', 'Strict no-logs'],
|
||
'hero.t3': ['端到端加密', 'End-to-end encrypted'],
|
||
'orb.cap': ['已连接', 'CONNECTED'],
|
||
'orb.down': ['下载', 'Down'],
|
||
'orb.up': ['上传', 'Up'],
|
||
'orb.node': ['香港 · 流媒体', 'Hong Kong'],
|
||
'orb.nodesub': ['延迟 18ms · 已连接', '18ms · Connected'],
|
||
|
||
'strip.txt': ['已支持', 'Available on'],
|
||
|
||
'feat.eyebrow': ['产品', 'Product'],
|
||
'feat.h': ['为日常而生的连接体验', 'Built for everyday connection'],
|
||
'feat.sub': ['没有复杂配置,没有技术门槛。打开就用,把稳定与隐私留给我们。', 'No complex setup, no jargon. Just open and go — we handle speed and privacy.'],
|
||
'feat.1t': ['一键连接', 'One-tap connect'],
|
||
'feat.1d': ['一颗按钮,智能挑选最快线路。无需手动配置,也能秒连。', 'One button picks the fastest route. No manual setup, instant connect.'],
|
||
'feat.2t': ['智能分流', 'Smart routing'],
|
||
'feat.2d': ['按规则智能分流,该加速的加速,本地服务直连,互不打扰。', 'Smart rule-based routing — accelerate what needs it, keep local traffic direct.'],
|
||
'feat.3t': ['80+ 全球加速线路', '80+ global routes'],
|
||
'feat.3d': ['覆盖港日新美欧韩等地,视频与游戏优化线路随心选。', 'Routes across HK / JP / SG / US / EU and more, tuned for video & gaming.'],
|
||
'feat.4t': ['严格无日志', 'Strict no-logs'],
|
||
'feat.4d': ['我们不记录你的浏览数据。隐私是底线,不是卖点。', 'We never log your browsing. Privacy is the baseline, not a feature.'],
|
||
'feat.5t': ['Kill Switch', 'Kill Switch'],
|
||
'feat.5d': ['一旦连接中断,立即阻断网络,杜绝真实 IP 泄露。', 'If the tunnel drops, traffic is blocked instantly — no IP leaks.'],
|
||
'feat.6t': ['多端同步', 'Multi-device'],
|
||
'feat.6d': ['一个账户,手机、平板、电脑同时在线,最多 5 台设备。', 'One account across phone, tablet and desktop — up to 5 devices.'],
|
||
|
||
'price.eyebrow': ['定价', 'Pricing'],
|
||
'price.h': ['简单透明的价格', 'Simple, honest pricing'],
|
||
'price.sub': ['随时升级或取消。所有套餐均含核心加密与无日志承诺。', 'Upgrade or cancel anytime. Every plan includes core encryption and our no-logs promise.'],
|
||
'price.monthly': ['按月', 'Monthly'],
|
||
'price.yearly': ['按年', 'Yearly'],
|
||
'price.save': ['省 20%', 'Save 20%'],
|
||
'price.permo': ['/月', '/mo'],
|
||
'price.free': ['免费版', 'Free'],
|
||
'price.freedesc': ['适合轻度使用与尝鲜', 'For light, casual use'],
|
||
'price.pro': ['专业版', 'Pro'],
|
||
'price.prodesc': ['个人用户的最佳选择', 'Best for individuals'],
|
||
'price.team': ['团队版', 'Team'],
|
||
'price.teamdesc': ['小团队集中管理', 'For small teams'],
|
||
'price.popular': ['最受欢迎', 'Most popular'],
|
||
'price.cta_free': ['免费下载', 'Download free'],
|
||
'price.cta_pro': ['获取激活码', 'Get a code'],
|
||
'price.cta_team': ['获取激活码', 'Get a code'],
|
||
'pf.free1': ['每日 10 分钟时长', '10 min per day'],
|
||
'pf.free2': ['仅 1 个基础节点', '1 basic node only'],
|
||
'pf.free3': ['使用前观看广告', 'Watch an ad to start'],
|
||
'pf.free4': ['核心加密 · 无日志', 'Core encryption · no-logs'],
|
||
'pf.pro1': ['80+ 全球加速线路', '80+ global routes'],
|
||
'pf.pro2': ['无限流量 · 极速', 'Unlimited · top speed'],
|
||
'pf.pro3': ['5 台设备同时在线', '5 devices at once'],
|
||
'pf.pro4': ['流媒体 & P2P 优化', 'Streaming & P2P routes'],
|
||
'pf.pro5': ['Kill Switch · 智能分流', 'Kill Switch · smart routing'],
|
||
'pf.team1': ['专业版全部功能', 'Everything in Pro'],
|
||
'pf.team2': ['10 个成员席位', '10 seats'],
|
||
'pf.team3': ['集中计费与管理', 'Central billing & admin'],
|
||
'pf.team4': ['优先客服', 'Priority support'],
|
||
|
||
'pay.title': ['为什么网页上没有支付按钮?', 'Why no checkout on this page?'],
|
||
'pay.body': ['出于风控与隐私考虑,穿山甲不在网页或 App 内直接收款。你可以通过以下任一渠道获取激活码,在客户端内兑换即可开通。', 'For risk and privacy reasons, Pangolin never takes payment in the web or app. Get an activation code through any channel below, then redeem it in the client.'],
|
||
'pay.store': ['自助发卡商店', 'Self-serve store'],
|
||
|
||
'pay.usdt': ['USDT (TRC20) · 最隐私', 'USDT (TRC20) · most private'],
|
||
'cmp.h': ['功能对比', 'Compare plans'],
|
||
'cmp.feature': ['功能', 'Feature'],
|
||
'cmp.locations': ['可用线路', 'Routes'],
|
||
'cmp.data': ['流量', 'Data'],
|
||
'cmp.time': ['每日时长', 'Daily time'],
|
||
'cmp.time_free': ['10 分钟/天(试用期不限)', '10 min/day (trial: unlimited)'],
|
||
'cmp.devices': ['设备数', 'Devices'],
|
||
'cmp.speed': ['极速线路', 'Top-speed routes'],
|
||
'cmp.stream': ['视频优化', 'Video routes'],
|
||
'cmp.kill': ['Kill Switch', 'Kill Switch'],
|
||
'cmp.support': ['客服', 'Support'],
|
||
'cmp.unlimited': ['无限', 'Unlimited'],
|
||
'cmp.daily': ['不限', 'Unlimited'],
|
||
'cmp.basic': ['标准', 'Standard'],
|
||
'cmp.priority': ['优先', 'Priority'],
|
||
|
||
'dl.eyebrow': ['下载', 'Download'],
|
||
'dl.h': ['全平台,随处可用', 'Every platform, everywhere'],
|
||
'dl.sub': ['一个账户,所有设备同步。下载即用,无需配置。', 'One account syncs every device. Download and go.'],
|
||
'dl.get': ['下载', 'Download'],
|
||
|
||
'docs.eyebrow': ['文档', 'Docs'],
|
||
'docs.h': ['需要帮助?都在这里', 'Need help? It’s all here'],
|
||
'docs.sub': ['从快速上手到协议细节,清晰直接。', 'From quickstart to protocol details — clear and direct.'],
|
||
'docs.1t': ['快速开始', 'Quickstart'],
|
||
'docs.1d': ['三分钟完成注册、下载与首次连接。', 'Sign up, download and connect in three minutes.'],
|
||
'docs.2t': ['常见问题', 'FAQ'],
|
||
'docs.2d': ['连接、计费、设备与兑换码的常见疑问。', 'Connection, billing, devices and redeem codes.'],
|
||
'docs.3t': ['协议与安全', 'Protocol & security'],
|
||
'docs.3d': ['WireGuard、加密方式与无日志架构说明。', 'WireGuard, encryption and our no-logs architecture.'],
|
||
'docs.4t': ['隐私政策', 'Privacy policy'],
|
||
'docs.4d': ['我们收集什么、不收集什么,一目了然。', 'Exactly what we collect — and what we never do.'],
|
||
'docs.read': ['阅读', 'Read'],
|
||
|
||
'blog.eyebrow': ['Blog', 'Blog'],
|
||
'blog.h': ['来自团队的最新动态', 'Latest from the team'],
|
||
'blog.sub': ['产品更新、安全科普与节点公告。', 'Product updates, security explainers and node news.'],
|
||
'blog.1tag': ['产品更新', 'Product'],
|
||
'blog.1t': ['v2.4:更快的智能分流与全新统计页', 'v2.4: faster smart routing & a new stats tab'],
|
||
'blog.1d': ['本次更新重写了分流引擎,连接建立速度提升约 40%。', 'We rewrote the routing engine — connections are ~40% faster.'],
|
||
'blog.2tag': ['安全', 'Security'],
|
||
'blog.2t': ['无日志到底意味着什么?', 'What “no-logs” really means'],
|
||
'blog.2d': ['我们逐条拆解收集与不收集的数据,以及背后的架构。', 'A line-by-line look at what we keep — and what we never touch.'],
|
||
'blog.3tag': ['公告', 'News'],
|
||
'blog.3t': ['新增首尔与法兰克福高速节点', 'New high-speed nodes: Seoul & Frankfurt'],
|
||
'blog.3d': ['两条新线路已上线,为东北亚与欧洲用户带来更低延迟。', 'Two new routes are live, cutting latency for NE Asia and Europe.'],
|
||
'blog.readmore': ['阅读全文', 'Read more'],
|
||
|
||
'cta.h': ['准备好体验极速畅连了吗?', 'Ready for a faster connection?'],
|
||
'cta.p': ['免费下载,数分钟内开始你的第一次极速连接。', 'Download free and get connected in minutes.'],
|
||
'cta.btn': ['免费下载', 'Download free'],
|
||
|
||
'ft.tag': ['极简、轻量、亲和的跨平台网络加速应用。守护你的每一次连接。', 'A minimal, friendly cross-platform network accelerator. Protecting every connection.'],
|
||
'ft.product': ['产品', 'Product'],
|
||
'ft.resources': ['资源', 'Resources'],
|
||
'ft.contact': ['联系与渠道', 'Contact'],
|
||
'ft.features': ['功能', 'Features'],
|
||
'ft.pricing': ['定价', 'Pricing'],
|
||
'ft.download': ['下载', 'Download'],
|
||
'ft.docs': ['文档', 'Docs'],
|
||
'ft.blog': ['Blog', 'Blog'],
|
||
'ft.faq': ['常见问题', 'FAQ'],
|
||
'ft.privacy': ['隐私政策', 'Privacy'],
|
||
'ft.status': ['服务状态', 'Status'],
|
||
'ft.hours': ['服务时间 每日 9:00–24:00 (GMT+8)', 'Hours: Daily 9:00–24:00 (GMT+8)'],
|
||
'ft.copy': ['© 2026 穿山甲 · Pangolin', '© 2026 Pangolin'],
|
||
'ft.madenote': ['App 内不支持直接支付 · 资金流全走外部渠道', 'No in-app payment · all purchases via external channels'],
|
||
};
|
||
|
||
let lang = localStorage.getItem('pg_site_lang') || 'zh';
|
||
|
||
function applyLang() {
|
||
const i = lang === 'zh' ? 0 : 1;
|
||
document.documentElement.lang = lang === 'zh' ? 'zh' : 'en';
|
||
document.querySelectorAll('[data-i18n]').forEach((el) => {
|
||
const k = el.getAttribute('data-i18n');
|
||
if (I18N[k]) el.textContent = I18N[k][i];
|
||
});
|
||
document.querySelectorAll('[data-i18n-ph]').forEach((el) => {
|
||
const k = el.getAttribute('data-i18n-ph');
|
||
if (I18N[k]) el.placeholder = I18N[k][i];
|
||
});
|
||
document.querySelectorAll('.langseg button').forEach((b) => b.classList.toggle('on', b.dataset.lang === lang));
|
||
}
|
||
window.__setLang = function (l) { lang = l; localStorage.setItem('pg_site_lang', l); applyLang(); };
|
||
|
||
// ---------- pricing monthly/yearly ----------
|
||
const PRICES = { free: ['¥0', '¥0'], pro: ['¥25', '¥20'], team: ['¥99', '¥79'] };
|
||
let cycle = 'monthly';
|
||
window.__setCycle = function (c) {
|
||
cycle = c;
|
||
const i = c === 'monthly' ? 0 : 1;
|
||
document.querySelectorAll('[data-price]').forEach((el) => {
|
||
const p = el.getAttribute('data-price');
|
||
el.firstChild.textContent = PRICES[p][i];
|
||
});
|
||
document.querySelectorAll('.price-toggle button').forEach((b) => b.classList.toggle('on', b.dataset.cycle === c));
|
||
};
|
||
|
||
// ---------- signup (demo: real impl sends a verification code) ----------
|
||
window.__signup = function (e) {
|
||
e.preventDefault();
|
||
const em = document.getElementById('su-email');
|
||
if (!/\S+@\S+\.\S+/.test(em.value)) { em.focus(); return false; }
|
||
document.getElementById('su-ok').hidden = false;
|
||
return false;
|
||
};
|
||
|
||
// ---------- announcement bar ----------
|
||
window.__closeAnn = function () {
|
||
const a = document.getElementById('ann');
|
||
if (a) a.remove();
|
||
};
|
||
|
||
// ---------- mobile menu ----------
|
||
window.__toggleMenu = function () {
|
||
document.getElementById('mnav').classList.toggle('open');
|
||
};
|
||
|
||
// ---------- scroll glass header ----------
|
||
function onScroll() {
|
||
document.querySelector('.hdr').classList.toggle('scrolled', window.scrollY > 8);
|
||
}
|
||
window.addEventListener('scroll', onScroll, { passive: true });
|
||
|
||
// ---------- init ----------
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
applyLang();
|
||
onScroll();
|
||
// close mobile menu when a link is tapped
|
||
document.querySelectorAll('#mnav a').forEach((a) =>
|
||
a.addEventListener('click', () => document.getElementById('mnav').classList.remove('open')));
|
||
if (window.lucide) lucide.createIcons();
|
||
});
|
||
})();
|