// Bilingual i18n dictionary for app.html

const APP_I18N = {
  en: {
    common: {
      search: "Search…",
      save: "Save",
      cancel: "Cancel",
      delete: "Delete",
      online: "online",
      offline: "offline",
      signOut: "Sign out",
      settings: "Settings",
      language: "Language",
      theme: "Theme",
      light: "Light",
      dark: "Dark",
      backToSite: "Back to site",
      upgrade: "Upgrade",
    },
    roles: {
      owner: "Owner",
      editor: "Editor",
      reader: "Reader",
    },
    plans: { free: "Basic", pro: "Pro", enterprise: "Enterprise" },
    nav: {
      networks: "Network",
      support: "Support",
    },
    networks: {
      title: "Networks",
      new: "New network",
      name: "Name",
      cidr: "CIDR",
      plan: "Plan",
      devices: "Devices",
      lastActivity: "Last activity",
    },
    network: {
      devicesTab: "Devices",
      topologyTab: "Topology",
      performanceTab: "Performance",
      routesTab: "Routes",
      dnsTab: "MagicDNS",
      aclTab: "ACL",
      qosTab: "QoS",
      netflowTab: "Traffic",
      auditTab: "Audit",
      billingTab: "Billing",
      settingsTab: "Settings",
      ruleSrc: "src",
      ruleDst: "dst",
      ruleVia: "via",
      ruleNat: "NAT",
      ruleAction: "action",
      ruleKind: "kind",
      routesAdvTitle: "Route advertisements",
      routesAdvHelp: "Each node (node:xxx) advertises CIDRs it can reach inside the mesh. Nodes install accepted advertisements as system routes.",
      routesAdvBy: "advertised by",
      routesAdvType: "type",
      routesStatus: "status",
      routesCidr: "route",
      routesMasqTitle: "Masquerade rules",
      routesMasqHelp: "Pin out-of-mesh traffic to a specific egress node. Src is node:xxx or a CIDR. Dst is anything NOT covered by an advertisement — L3: external CIDR; L7: hostname (wildcard / regex). Toggle NAT on the via node if needed.",
      routesRule: "Rule",
      aclTitle: "ACL rules",
      aclRule: "Rule",
      aclHelp: "Filter traffic. Src is node:xxx or CIDR. Dst is node:xxx, CIDR, or hostname (wildcard / regex — L7 only). Default deny. Top-down evaluation; first match wins.",
      dnsHelp: "MagicDNS serves *.widewired hostnames from node gossip. No resolver config needed.",
      qosHelp: "QoS rules tag matching flows with DSCP and enforce rate limits at each node. Applied at egress on the sending node.",
      qosRules: "Rules",
      qosAdd: "Rule",
      qosMatch: "match",
      qosDscp: "DSCP",
      qosRate: "rate",
      qosPriority: "priority",
      netflowChart: "Throughput · last 60 min (Mbps)",
      netflowProto: "Protocol mix",
      netflowTop: "Top flows",
      netflowPair: "pair",
      netflowProtoCol: "proto/port",
      netflowBytes: "bytes",
      netflowFlows: "flows",
      netflowSearch: "Search flows…",
      netflowAllProto: "all protocols",
      netflowAllPeer: "all nodes",
      installCode: "Config code",
      installCopy: "Copy",
      installRegen: "Regenerate",
      installExpiry: "Expires in 14:52",
      auditTitle: "Audit log",
      auditAllActions: "all actions",
      auditTimestamp: "timestamp",
      auditAction: "action",
      auditSubject: "subject",
      auditActor: "actor",
      auditIp: "ip",
      devicesTitle: "Devices",
      exportCsv: "Export CSV",
      approve: "Approve",
      revoke: "Revoke",
      pending: "pending",
      deviceColumns: ["name", "ip", "os", "status", "last seen"],
      membersTitle: "Members",
      membersHelp: "Invite users to this network. Each member gets a per-network role: Owner manages billing & settings, Editor edits config, Reader has read-only access.",
      addressTitle: "Network CIDR",
      addressHelp: "The network CIDR defines the IP pool assigned to nodes. Changing the CIDR re-addresses every node on next handshake.",
      addressNetwork: "Network",
      addressUsable: "Usable",
      addressHosts: "hosts",
      addressUsed: "Assigned",
      settingsGeneral: "General",
      tokensTitle: "API tokens",
      deleteBody: "Deleting this network removes all devices, ACL, DNS, NetFlow history, and invoices. This cannot be undone.",
    },
    topology: {
      graph: "Graph",
    },
    matrix: {
      title: "Connectivity matrix",
      legend: ["direct", "user_relay", "managed_relay", "unreachable"],
      selected: "selected",
      rtt: "rtt",
      loss: "loss",
      path: "path",
      hint: "Click a cell to inspect the pair. Hover for RTT.",
    },
    members: {
      invite: "Invite",
      member: "member",
      role: "Role",
      joined: "Joined",
      lastSeen: "Last seen",
      inviteEmail: "Email",
      inviteRole: "Role",
      sendInvite: "Send invite",
    },
    billing: {
      invoices: "Invoices",
      invoiceDate: "Date",
      invoiceAmount: "Amount",
      invoiceItem: "Item",
      invoiceStatus: "Status",
      invoiceDownload: "PDF",
      current: "current",
      downgrade: "Downgrade",
      freeBlurb: "Up to 10 devices · community support",
      proBlurb: "Up to 100 devices · managed_relay · IPSec bridge",
      entBlurb: "Unlimited devices · SSO · audit export · SLA",
      infoTitle: "Billing information",
      company: "Company",
      taxId: "Tax ID / VAT",
      address1: "Street address",
      city: "City",
      postal: "Postal code",
      country: "Country",
      email: "Billing email",
      method: "Payment method",
      update: "Update",
    },
    tokens: {
      accountHint: "Account-level token. Authenticates as your user across every network you can access. Treat it like a password.",
      networkHint: "Network-level token. Scoped to this network only — it cannot read or modify any other network.",
      add: "Token",
      revoke: "revoke",
      colName: "name",
      colToken: "token",
      colScopes: "scopes",
      colCreated: "created",
      colExpires: "expires",
    },
    settings: {
      title: "Settings",
      account: "Account",
      name: "Name",
      email: "Email",
      mfa: "Multi-factor authentication",
      mfaOn: "Enabled",
      configure: "Configure",
      password: "Password",
      passwordHint: "Last changed 2026-02-04",
      changePassword: "Change password",
      dangerZone: "Danger zone",
      deleteBody: "Deleting your account removes you from every network. Networks you solely own will be archived. This cannot be undone.",
      deleteMe: "Delete my account",
      tokensTitle: "API tokens",
    },
    support: {
      newTicket: "New ticket",
      opened: "opened",
      subject: "subject",
      state: "state",
      lastUpdate: "last update",
    },
  },

  zh: {
    common: {
      search: "搜索…",
      save: "保存",
      cancel: "取消",
      delete: "删除",
      online: "在线",
      offline: "离线",
      signOut: "退出登录",
      settings: "设置",
      language: "语言",
      theme: "主题",
      light: "浅色",
      dark: "深色",
      backToSite: "返回官网",
      upgrade: "升级",
    },
    roles: {
      owner: "所有者",
      editor: "编辑",
      reader: "只读",
    },
    plans: { free: "基础版", pro: "专业版", enterprise: "企业版" },
    nav: {
      networks: "网络",
      support: "支持",
    },
    networks: {
      title: "网络",
      new: "新建网络",
      name: "名称",
      cidr: "网段",
      plan: "计划",
      devices: "设备",
      lastActivity: "最近活动",
    },
    network: {
      devicesTab: "设备",
      topologyTab: "拓扑",
      performanceTab: "性能",
      routesTab: "路由",
      dnsTab: "MagicDNS",
      aclTab: "ACL",
      qosTab: "QoS",
      netflowTab: "流量",
      auditTab: "审计",
      billingTab: "账单",
      settingsTab: "设置",
      ruleSrc: "来源",
      ruleDst: "目标",
      ruleVia: "出口",
      ruleNat: "NAT",
      ruleAction: "动作",
      ruleKind: "类型",
      routesAdvTitle: "路由宣告",
      routesAdvHelp: "每个节点（node:xxx）宣告它在网内可达的网段。被接受的宣告会作为系统路由安装到各 node。",
      routesAdvBy: "宣告设备",
      routesAdvType: "类型",
      routesStatus: "状态",
      routesCidr: "网段",
      routesMasqTitle: "伪装规则",
      routesMasqHelp: "将网外流量固定到指定出口节点。来源为 node:xxx 或 CIDR；目标为不在路由宣告范围内的对象 —— L3：外部网段；L7：域名（通配符或正则）。需要时在出口节点开启 NAT。",
      routesRule: "规则",
      aclTitle: "ACL 规则",
      aclRule: "规则",
      aclHelp: "过滤流量。来源为 node:xxx 或 CIDR；目标为 node:xxx、CIDR 或域名（通配符 / 正则，仅 L7）。默认拒绝；规则按顺序匹配，命中即停。",
      dnsHelp: "MagicDNS 通过 node gossip 服务 *.widewired 主机名，客户端无需配置解析器。",
      qosHelp: "QoS 规则为匹配的流打 DSCP 标记，并在每个 node 上执行速率限制。在发送端出方向生效。",
      qosRules: "规则",
      qosAdd: "规则",
      qosMatch: "匹配",
      qosDscp: "DSCP",
      qosRate: "速率",
      qosPriority: "优先级",
      netflowChart: "吞吐 · 近 60 分钟（Mbps）",
      netflowProto: "协议分布",
      netflowTop: "头部流量",
      netflowPair: "通信对",
      netflowProtoCol: "协议/端口",
      netflowBytes: "字节数",
      netflowFlows: "流数",
      netflowSearch: "搜索流量…",
      netflowAllProto: "全部协议",
      netflowAllPeer: "全部 node",
      installCode: "配置码",
      installCopy: "复制",
      installRegen: "重新生成",
      installExpiry: "14:52 后失效",
      auditTitle: "审计日志",
      auditAllActions: "全部动作",
      auditTimestamp: "时间",
      auditAction: "动作",
      auditSubject: "对象",
      auditActor: "操作人",
      auditIp: "IP",
      devicesTitle: "设备",
      exportCsv: "导出 CSV",
      approve: "批准",
      revoke: "撤销",
      pending: "待审批",
      deviceColumns: ["名称", "IP", "系统", "状态", "最后在线"],
      membersTitle: "成员",
      membersHelp: "邀请用户加入本网络。每位成员拥有网络内角色：所有者可管理账单与设置，编辑可修改配置，只读仅可查看。",
      addressTitle: "网络 CIDR",
      addressHelp: "网段定义了分配给 node 的 IP 池。修改网段后，各 node 将在下次握手时重新分配地址。",
      addressNetwork: "网络",
      addressUsable: "可用",
      addressHosts: "主机数",
      addressUsed: "已分配",
      settingsGeneral: "基本",
      tokensTitle: "API Token",
      deleteBody: "删除本网络将移除所有设备、ACL、DNS、NetFlow 历史与发票。此操作不可撤销。",
    },
    topology: {
      graph: "拓扑图",
    },
    matrix: {
      title: "连通矩阵",
      legend: ["直连", "自有中继", "托管中继", "不可达"],
      selected: "选中",
      rtt: "RTT",
      loss: "丢包",
      path: "路径",
      hint: "点击单元格查看详情。悬停查看 RTT。",
    },
    members: {
      invite: "邀请",
      member: "成员",
      role: "角色",
      joined: "加入时间",
      lastSeen: "最后在线",
      inviteEmail: "邮箱",
      inviteRole: "角色",
      sendInvite: "发送邀请",
    },
    billing: {
      invoices: "发票",
      invoiceDate: "日期",
      invoiceAmount: "金额",
      invoiceItem: "项目",
      invoiceStatus: "状态",
      invoiceDownload: "PDF",
      current: "当前",
      downgrade: "降级",
      freeBlurb: "最多 10 台设备 · 社区支持",
      proBlurb: "最多 100 台设备 · 托管中继 · IPSec 桥接",
      entBlurb: "无限设备 · SSO · 审计导出 · SLA",
      infoTitle: "账单信息",
      company: "公司名称",
      taxId: "税号 / VAT",
      address1: "详细地址",
      city: "城市",
      postal: "邮编",
      country: "国家 / 地区",
      email: "账单邮箱",
      method: "支付方式",
      update: "更新",
    },
    tokens: {
      accountHint: "账号级 Token。以你账号身份访问所有可见网络，请像保管密码一样妥善保管。",
      networkHint: "网络级 Token。仅作用于本网络，无法读取或修改其他网络。",
      add: "Token",
      revoke: "撤销",
      colName: "名称",
      colToken: "Token",
      colScopes: "权限",
      colCreated: "创建时间",
      colExpires: "过期时间",
    },
    settings: {
      title: "设置",
      account: "账号",
      name: "姓名",
      email: "邮箱",
      mfa: "多因素认证",
      mfaOn: "已启用",
      configure: "配置",
      password: "密码",
      passwordHint: "上次修改 2026-02-04",
      changePassword: "修改密码",
      dangerZone: "危险操作",
      deleteBody: "删除账号后你将被移出所有网络。由你独自拥有的网络将被归档。此操作不可撤销。",
      deleteMe: "删除我的账号",
      tokensTitle: "API Token",
    },
    support: {
      newTicket: "新建工单",
      opened: "创建时间",
      subject: "主题",
      state: "状态",
      lastUpdate: "最近更新",
    },
  },
};

window.APP_I18N = APP_I18N;
