dsh-deeppilot 0.9.15 → 0.9.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["h","useRef","h","h","useReducer","useState","useId","useRef","t","deviceLabel","deviceLabelOf","visibleDevices","visibleDevicesOf","Switch","Button","h","registerDeepPilotLocale"],"sources":["../src/client/snapshot-store.ts","../src/tailscale-version.ts","../src/device-auth.ts","../src/report-wire.ts","../src/client/report-mount.ts","../src/client/i18n.ts","../src/client/styles.ts","../src/client/settings-icons.ts","../src/client/device-actions.ts","../node_modules/qrcode/lib/can-promise.js","../node_modules/qrcode/lib/core/utils.js","../node_modules/qrcode/lib/core/error-correction-level.js","../node_modules/qrcode/lib/core/bit-buffer.js","../node_modules/qrcode/lib/core/bit-matrix.js","../node_modules/qrcode/lib/core/alignment-pattern.js","../node_modules/qrcode/lib/core/finder-pattern.js","../node_modules/qrcode/lib/core/mask-pattern.js","../node_modules/qrcode/lib/core/error-correction-code.js","../node_modules/qrcode/lib/core/galois-field.js","../node_modules/qrcode/lib/core/polynomial.js","../node_modules/qrcode/lib/core/reed-solomon-encoder.js","../node_modules/qrcode/lib/core/version-check.js","../node_modules/qrcode/lib/core/regex.js","../node_modules/qrcode/lib/core/mode.js","../node_modules/qrcode/lib/core/version.js","../node_modules/qrcode/lib/core/format-info.js","../node_modules/qrcode/lib/core/numeric-data.js","../node_modules/qrcode/lib/core/alphanumeric-data.js","../node_modules/qrcode/lib/core/byte-data.js","../node_modules/qrcode/lib/core/kanji-data.js","../node_modules/dijkstrajs/dijkstra.js","../node_modules/qrcode/lib/core/segments.js","../node_modules/qrcode/lib/core/qrcode.js","../node_modules/qrcode/lib/renderer/utils.js","../node_modules/qrcode/lib/renderer/canvas.js","../node_modules/qrcode/lib/renderer/svg-tag.js","../node_modules/qrcode/lib/browser.js","../src/pairing-qr.ts","../src/client/pairing-panel.ts","../src/funnel-policy.ts","../src/local-policy.ts","../src/client/settings-props.ts","../src/client/settings-view-models.ts","../src/client/settings-page.ts","../src/client/nav-icon.ts","../src/client/config-form.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Tiny observable snapshot store consumed by the harness slot renderer's\n * `useSyncExternalStore` hooks.\n *\n * Kept local because the rc.2 browser module table does not publish\n * `@deepseek-ai/dsh-client-store` for external plugins. The generated bundle\n * therefore has no unavailable runtime dependency.\n */\nexport interface SnapshotStore<T> {\n getSnapshot(): T\n subscribe(listener: () => void): () => void\n set(value: T): void\n}\n\nexport function createSnapshotStore<T>(initial: T): SnapshotStore<T> {\n let snapshot = initial\n const listeners = new Set<() => void>()\n return {\n getSnapshot: () => snapshot,\n subscribe(listener) {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n set(value) {\n if (Object.is(value, snapshot)) return\n snapshot = value\n for (const listener of listeners) listener()\n },\n }\n}\n","/**\n * 内嵌 helper 上报的 tailscale.com 模块版本。\n *\n * 版本的唯一来源是 helper 启动事件(`helper/main.go` 读 Go 构建信息里的\n * `tailscale.com` 依赖版本),不是 go.mod、也不是插件常量:用户可能通过\n * `remote.helperPath` 换成自己编译的 helper,界面必须显示实际在跑的那一个。\n *\n * 两条边界都要守卫:\n * - 宿主侧 `parseHelperEvent` 把 helper 的 stdout 当成不可信输入,格式不对\n * 就丢弃,避免把任意文本渲染进设置页;\n * - 设置页侧 `reportSchema` 同样校验 Host RPC 返回值,旧 Host 不带该字段\n * 时保持 undefined(页面显示「未获取」),不当作错误。\n *\n * 接受 Go 模块版本形态:`v1.104.2`、`v1.104.2-pre.1`、\n * `v0.0.0-20260101000000-abcdef123456`。长度上限防止异常输入撑爆界面。\n */\nexport const TAILSCALE_VERSION_PATTERN = /^v?\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]{1,64})?$/\n\nconst MAX_TAILSCALE_VERSION_LENGTH = 80\n\n/** 判断外部输入是否是合法的 Tailscale 模块版本字符串。 */\nexport function isTailscaleVersion(value: unknown): value is string {\n return typeof value === 'string' &&\n value.length <= MAX_TAILSCALE_VERSION_LENGTH &&\n TAILSCALE_VERSION_PATTERN.test(value)\n}\n","import {\n createHash,\n createPublicKey,\n randomBytes,\n timingSafeEqual,\n verify,\n type KeyObject,\n} from 'node:crypto'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { formatLogLine } from './diagnostics.ts'\n\nexport function getPairingCodeTtlMs(): number {\n return Number(process.env.DEEPPILOT_PAIRING_TTL_MS) || 5 * 60_000\n}\nexport const AUTH_CHALLENGE_TTL_MS = 30_000\n\nexport const DEVICE_SCOPES = [\n 'sessions.read',\n 'prompt.send',\n 'sessions.manage',\n 'interactions.respond',\n 'notifications.register',\n 'schedule.manage',\n] as const\n\nexport type DeviceScope = (typeof DEVICE_SCOPES)[number]\n\nexport const DEFAULT_DEVICE_SCOPES: readonly DeviceScope[] = DEVICE_SCOPES\n\nexport interface PairingGrant {\n code: string\n expiresAt: number\n audience?: string\n}\n\nexport async function loadOrCreateHostAudience(path: string): Promise<string> {\n try {\n const existing = (await readFile(path, 'utf8')).trim()\n if (/^deeppilot:[A-Za-z0-9_-]{22}$/.test(existing)) return existing\n throw new Error(`host audience is malformed at ${path}`)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n }\n const audience = 'deeppilot:' + randomBytes(16).toString('base64url')\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, audience + '\\n', { mode: 0o600 })\n // 新建 Host 身份意味着 audience 变了:所有此前配对的设备都会在下一步\n // 认证失败(audience-mismatch)。这是「手机突然全部要重新配对」最直接的\n // 证据,必须留一行;只记事实与路径,不记 audience 原文(可被冒充)。\n console.log(formatLogLine('info', 'host identity created: ' + path + ' (previously paired devices must pair again)'))\n return audience\n}\n\nexport interface AuthChallenge {\n nonce: string\n audience: string\n issuedAt: number\n expiresAt: number\n}\n\nexport interface AuthProofFields extends AuthChallenge {\n deviceId: string\n deviceName: string\n appVersion: string\n resumeCursor?: number\n}\n\nfunction b64urlText(value: string): string {\n return Buffer.from(value, 'utf8').toString('base64url')\n}\n\n/**\n * Cross-language signature input. Text fields are base64url encoded before\n * joining so names cannot create ambiguous separators. Decimal timestamps\n * and cursor values are finite integers, or `-` when the cursor is absent.\n */\nexport function canonicalAuthChallenge(fields: AuthProofFields): Buffer {\n const cursor = fields.resumeCursor === undefined ? '-' : String(fields.resumeCursor)\n return Buffer.from([\n 'deeppilot-auth-v2',\n `device-id:${b64urlText(fields.deviceId)}`,\n `nonce:${fields.nonce}`,\n `audience:${b64urlText(fields.audience)}`,\n `issued-at:${fields.issuedAt}`,\n `expires-at:${fields.expiresAt}`,\n `device-name:${b64urlText(fields.deviceName)}`,\n `app-version:${b64urlText(fields.appVersion)}`,\n `resume-cursor:${cursor}`,\n ].join('\\n'), 'utf8')\n}\n\n/** Accept only an uncompressed ANSI X9.63 P-256 public key (65 bytes). */\nexport function parseP256PublicKey(encoded: string): { key: KeyObject; raw: Buffer } {\n const raw = Buffer.from(encoded, 'base64url')\n if (raw.length !== 65 || raw[0] !== 0x04) {\n throw new TypeError('publicKey must be an uncompressed P-256 X9.63 key')\n }\n // SubjectPublicKeyInfo prefix for id-ecPublicKey / prime256v1 followed by\n // the 65-byte uncompressed point.\n const spkiPrefix = Buffer.from('3059301306072a8648ce3d020106082a8648ce3d030107034200', 'hex')\n const key = createPublicKey({ key: Buffer.concat([spkiPrefix, raw]), format: 'der', type: 'spki' })\n if (key.asymmetricKeyType !== 'ec' || key.asymmetricKeyDetails?.namedCurve !== 'prime256v1') {\n throw new TypeError('publicKey must use P-256')\n }\n return { key, raw }\n}\n\nexport function deviceIdForPublicKey(publicKey: string): string {\n const { raw } = parseP256PublicKey(publicKey)\n return createHash('sha256').update(raw).digest('base64url')\n}\n\nexport function fingerprintForPublicKey(publicKey: string): string {\n const { raw } = parseP256PublicKey(publicKey)\n return createHash('sha256').update(raw).digest('hex')\n}\n\nexport function verifyAuthProof(publicKey: string, fields: AuthProofFields, signature: string): boolean {\n try {\n const { key } = parseP256PublicKey(publicKey)\n const der = Buffer.from(signature, 'base64url')\n if (der.length < 64 || der.length > 80) return false\n return verify('sha256', canonicalAuthChallenge(fields), key, der)\n } catch {\n return false\n }\n}\n\nexport function normalizeDeviceScopes(value: unknown): DeviceScope[] {\n if (!Array.isArray(value)) return [...DEFAULT_DEVICE_SCOPES]\n const allowed = new Set<string>(DEVICE_SCOPES)\n return [...new Set(value.filter((scope): scope is DeviceScope => typeof scope === 'string' && allowed.has(scope)))]\n}\n\n/**\n * 0.8.3 之前的「全部权限」:当时还没有 `schedule.manage`。App 配对时一直申请\n * DeviceScope 的全部取值,设置页也没有收窄权限的入口,所以存量记录恰好等于这五项,\n * 只说明「配对时这项权限还不存在」,不是有意关闭。\n */\nconst LEGACY_FULL_SCOPES: readonly DeviceScope[] = [\n 'sessions.read',\n 'prompt.send',\n 'sessions.manage',\n 'interactions.respond',\n 'notifications.register',\n]\n\n/**\n * 存量设备权限升级:恰好等于旧版全部权限时补上之后新增的默认权限,返回新列表;\n * 其余情况(含任何非完整集合)返回 null,原样保留。只放宽「旧版全量」这一种形态,\n * 避免把将来可能出现的、有意收窄过的记录一并放开。\n */\nexport function upgradeLegacyFullScopes(value: unknown): DeviceScope[] | null {\n if (!Array.isArray(value)) return null\n const current = new Set(value)\n if (current.size !== LEGACY_FULL_SCOPES.length) return null\n if (!LEGACY_FULL_SCOPES.every((scope) => current.has(scope))) return null\n return [...DEFAULT_DEVICE_SCOPES]\n}\n\n/** One active, single-use pairing grant per plugin runtime. */\nexport class PairingCodeManager {\n private active: PairingGrant | null = null\n\n issue(now = Date.now()): PairingGrant {\n const grant = {\n code: randomBytes(24).toString('base64url'),\n expiresAt: now + getPairingCodeTtlMs(),\n }\n this.active = grant\n return { ...grant }\n }\n\n consume(presented: string, now = Date.now()): boolean {\n const active = this.active\n if (active === null || now > active.expiresAt) {\n this.active = null\n return false\n }\n const expected = Buffer.from(active.code)\n const actual = Buffer.from(presented)\n const matches = expected.length === actual.length && timingSafeEqual(expected, actual)\n if (matches) this.active = null\n return matches\n }\n\n invalidate(): void {\n this.active = null\n }\n}\n\nexport function createAuthChallenge(audience: string, now = Date.now()): AuthChallenge {\n return {\n nonce: randomBytes(24).toString('base64url'),\n audience,\n issuedAt: now,\n expiresAt: now + AUTH_CHALLENGE_TTL_MS,\n }\n}\n","/**\n * Wire contract for the DeepPilot report Remote (`deeppilot/report`).\n *\n * The web settings page needs the bridge's live facts (paired devices,\n * connections, token state) — those live Host-side. This module is the single\n * source both halves share: the strict result codec (hand-rolled, so the\n * client bundle needs no schema library) and the exact descriptor object.\n *\n * @module dsh-deeppilot/report-wire\n */\n\nimport type { InvocationDescriptor, TypertCodec, TypertRemoteContribution, TypertSchema } from '@deepseek-ai/dsh-typert-protocol'\nimport { isTailscaleVersion } from './tailscale-version.ts'\nimport { DEVICE_SCOPES, normalizeDeviceScopes, type DeviceScope } from './device-auth.ts'\n\nexport interface PairingGrantSnapshot {\n code: string\n expiresAt: number\n audience: string\n}\n\n/** One paired device row in the report. */\nexport interface ReportDevice {\n deviceId: string\n /** Effective operator-facing name: customName when set, otherwise the app-reported name. */\n deviceName: string\n /** User-assigned label; absent means the app-reported name is in use. */\n customName?: string\n appVersion: string\n firstSeenTs: number\n lastSeenTs: number\n fingerprint: string\n scopes: DeviceScope[]\n revokedAt?: number\n /** Present once the device registered an APNs token (token itself never leaves the host). */\n apns?: { environment: 'development' | 'production'; updatedAt: number }\n}\n\n/** One step of the relay connectivity self-test. */\nexport interface RelayTestStep {\n id: 'health' | 'enroll'\n ok: boolean\n message: string\n latencyMs?: number\n}\n\n/** Result of deeppilot/testRelay. */\nexport interface RelayTestResult {\n url: string\n overall: 'ok' | 'failed'\n tokenIssued: boolean\n steps: RelayTestStep[]\n}\n\n/** Per-device delivery result of deeppilot/testPush. */\nexport interface PushTestDeviceResult {\n name: string\n environment: string\n /** sent | invalid-token | failed — mirrors the dispatch outcome contract. */\n outcome: string\n /** Apple's raw rejection reason when present (BadDeviceToken, …). */\n reason?: string\n /** First 10 hex chars of the stored token, for freshness verification. */\n tokenFingerprint?: string\n}\n\n/**\n * 设置页「连接诊断」区块展示的一条最近失败。\n *\n * 只携带可安全展示的结构化事实:类型、分因、时间、来源哈希(auditLabel\n * 的 12 位十六进制,绝不是原始 IP)、可选 attemptId / 关闭码 / 耗时。\n * 配对码、公钥、APNs token、消息正文永远不进入这里。\n */\nexport interface ReportDiagnosticFailure {\n ts: number\n kind: string\n reason: string\n attemptId?: string\n source?: string\n closeCode?: number\n durationMs?: number\n}\n\n/** 连接诊断快照;不包含 debug 开关状态。 */\nexport interface ReportDiagnostics {\n /** 插件 apply() 的启动时刻。 */\n startedAt: number\n /** 最近失败事件(时间升序,最多 20 条)。 */\n recentFailures: ReportDiagnosticFailure[]\n}\n\nexport interface PushTestResult {\n transport: 'apns' | 'relay' | 'none'\n /** sent = at least one accepted delivery; no-targets / not-configured / failed. */\n overall: 'sent' | 'failed' | 'no-targets' | 'not-configured'\n message?: string\n results: PushTestDeviceResult[]\n}\n\n/** Everything the settings page renders for the bridge. */\nexport interface DeepPilotReport {\n protocolVersion: number\n serverVersion: string\n /** Host plugin version (from package.json). Same value as serverVersion,\n * surfaced under a stable name so the wire contract does not change if\n * the legacy field is ever repurposed. */\n pluginVersion: string\n /** True once the host's background GitHub check has confirmed a newer\n * stable release exists. Undefined / false ⇒ the UI shows only the\n * version line, never the \"new version\" hint. */\n updateAvailable?: boolean\n /** GitHub release page URL, when an update is available. */\n releaseUrl?: string\n /** Whether the master bridge switch is on. */\n enabled: boolean\n /** Absolute protocol-v2 identity registry path. */\n identityPath: string\n /** Whether host identity and the device registry are ready. */\n pairingReady: boolean\n /** Currently connected phone sockets. */\n activeConnections: number\n historyBufferMax: number\n /** Private IPv4 candidates for local QR pairing. */\n lanAddresses: string[]\n /** Independent TLS-only LAN listener; this never represents DSH's own web port. */\n local: {\n phase: 'disabled' | 'starting' | 'online' | 'error' | 'stopped'\n port: number\n endpoints: string[]\n /** `sha256:` SPKI pin of the LAN certificate; present while `online`. */\n tlsFingerprint?: string\n /** The LAN private key was recreated this run: paired LAN devices must pair again. */\n tlsIdentityRegenerated?: boolean\n message?: string\n updatedAt: number\n }\n remote: {\n provider: 'tailscale-funnel'\n phase: 'disabled' | 'starting' | 'login_required' | 'online' | 'error' | 'unavailable' | 'stopped'\n publicURL?: string\n authURL?: string\n message?: string\n /**\n * 内嵌 helper 自报的 tailscale.com 模块版本(如 `v1.104.2`)。可选:\n * 远程连接未启用、helper 缺失或尚未启动时 Host 不带这个字段,设置页\n * 显示「未获取」;旧 Host 同样不带,页面不能因此报错。\n */\n tailscaleVersion?: string\n updatedAt: number\n }\n devices: ReportDevice[]\n /**\n * 连接诊断。可选:旧 Host 不返回时设置页整块跳过,不当作错误。\n * 这是「最近失败」的唯一 report 通道(health 只服务手机)。\n */\n diagnostics?: ReportDiagnostics\n}\n\n/** The npm package identity both contribution registrations claim. */\nexport const REPORT_REMOTE_PACKAGE = 'dsh-deeppilot'\n\n/** Canonical `<namespace>/<method>` endpoint of the report Remote. */\nexport const REPORT_ENDPOINT = 'deeppilot/report'\n\nexport const BEGIN_PAIRING_ENDPOINT = 'deeppilot/beginPairing'\nexport const REVOKE_DEVICE_ENDPOINT = 'deeppilot/revokeDevice'\nexport const SET_DEVICE_NAME_ENDPOINT = 'deeppilot/setDeviceName'\nexport const SET_DEVICE_SCOPES_ENDPOINT = 'deeppilot/setDeviceScopes'\n\nfunction reject(field: string): never {\n throw new TypeError(`deeppilot/report result: invalid ${field}`)\n}\n\nfunction str(source: Record<string, unknown>, key: string, field: string): string {\n const value = source[key]\n if (typeof value !== 'string') reject(field)\n return value\n}\n\n/**\n * Non-negative integer: counters and timestamps (activeConnections,\n * historyBufferMax, updatedAt, lastSeenTs, protocolVersion, etc.). A bare\n * `typeof number` check accepts 1.5, -1, and 1e20 — all of which then\n * surface verbatim on the settings page and break any sort or arithmetic\n * the UI does.\n */\nfunction int(source: Record<string, unknown>, key: string, field: string): number {\n const value = source[key]\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n !Number.isInteger(value) ||\n value < 0\n ) reject(field)\n return value\n}\nfunction bool(source: Record<string, unknown>, key: string, field: string): boolean {\n const value = source[key]\n if (typeof value !== 'boolean') reject(field)\n return value\n}\nfunction rec(value: unknown, field: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) reject(field)\n return value as Record<string, unknown>\n}\n\nfunction parseDevice(value: unknown): ReportDevice {\n const s = rec(value, 'device')\n let apns: ReportDevice['apns']\n if (s.apns !== undefined) {\n const a = rec(s.apns, 'device.apns')\n const environment = str(a, 'environment', 'device.apns.environment')\n if (environment !== 'development' && environment !== 'production') reject('device.apns.environment')\n apns = { environment, updatedAt: int(a, 'updatedAt', 'device.apns.updatedAt') }\n }\n const customName = s.customName\n if (customName !== undefined && (\n typeof customName !== 'string' ||\n customName.length === 0 ||\n customName.length > 64 ||\n customName.trim() !== customName ||\n /[\\u0000-\\u001f\\u007f-\\u009f]/u.test(customName)\n )) reject('device.customName')\n return {\n deviceId: str(s, 'deviceId', 'device.deviceId'),\n deviceName: str(s, 'deviceName', 'device.deviceName'),\n ...(typeof customName === 'string' ? { customName } : {}),\n appVersion: str(s, 'appVersion', 'device.appVersion'),\n firstSeenTs: int(s, 'firstSeenTs', 'device.firstSeenTs'),\n lastSeenTs: int(s, 'lastSeenTs', 'device.lastSeenTs'),\n fingerprint: str(s, 'fingerprint', 'device.fingerprint'),\n scopes: normalizeDeviceScopes(s.scopes),\n ...(s.revokedAt !== undefined ? { revokedAt: int(s, 'revokedAt', 'device.revokedAt') } : {}),\n ...(apns ? { apns } : {}),\n }\n}\n\nfunction parseRemote(value: unknown): DeepPilotReport['remote'] {\n const s = rec(value, 'remote')\n const provider = str(s, 'provider', 'remote.provider')\n const phase = str(s, 'phase', 'remote.phase')\n if (provider !== 'tailscale-funnel') reject('remote.provider')\n const phases = ['disabled', 'starting', 'login_required', 'online', 'error', 'unavailable', 'stopped']\n if (!phases.includes(phase)) reject('remote.phase')\n const publicURL = s.publicURL\n const authURL = s.authURL\n const message = s.message\n const tailscaleVersion = s.tailscaleVersion\n if (publicURL !== undefined && typeof publicURL !== 'string') reject('remote.publicURL')\n if (authURL !== undefined && typeof authURL !== 'string') reject('remote.authURL')\n if (message !== undefined && typeof message !== 'string') reject('remote.message')\n // 页面直接渲染这个字符串:只接受 Go 模块版本形态,坏值拒绝整份报告,\n // 而不是把任意文本带进设置页。\n if (tailscaleVersion !== undefined && !isTailscaleVersion(tailscaleVersion)) reject('remote.tailscaleVersion')\n return {\n provider,\n phase: phase as DeepPilotReport['remote']['phase'],\n ...(typeof publicURL === 'string' ? { publicURL } : {}),\n ...(typeof authURL === 'string' ? { authURL } : {}),\n ...(typeof message === 'string' ? { message } : {}),\n ...(typeof tailscaleVersion === 'string' ? { tailscaleVersion } : {}),\n updatedAt: int(s, 'updatedAt', 'remote.updatedAt'),\n }\n}\n\nfunction parseLocal(value: unknown): DeepPilotReport['local'] {\n const s = rec(value, 'local')\n const phase = str(s, 'phase', 'local.phase')\n const phases = ['disabled', 'starting', 'online', 'error', 'stopped']\n if (!phases.includes(phase)) reject('local.phase')\n const endpoints = s.endpoints\n if (!Array.isArray(endpoints) || endpoints.some((entry) => typeof entry !== 'string')) reject('local.endpoints')\n const message = s.message\n if (message !== undefined && typeof message !== 'string') reject('local.message')\n const tlsFingerprint = s.tlsFingerprint\n if (tlsFingerprint !== undefined && typeof tlsFingerprint !== 'string') reject('local.tlsFingerprint')\n const tlsIdentityRegenerated = s.tlsIdentityRegenerated\n if (tlsIdentityRegenerated !== undefined && typeof tlsIdentityRegenerated !== 'boolean') reject('local.tlsIdentityRegenerated')\n return {\n phase: phase as DeepPilotReport['local']['phase'],\n port: int(s, 'port', 'local.port'),\n endpoints: endpoints as string[],\n ...(typeof tlsFingerprint === 'string' ? { tlsFingerprint } : {}),\n ...(tlsIdentityRegenerated === true ? { tlsIdentityRegenerated: true } : {}),\n ...(typeof message === 'string' ? { message } : {}),\n updatedAt: int(s, 'updatedAt', 'local.updatedAt'),\n }\n}\n\nfunction parseRelayTestStep(value: unknown): RelayTestStep {\n const st = rec(value, 'step')\n const id = str(st, 'id', 'step.id')\n if (id !== 'health' && id !== 'enroll') reject('step.id')\n const latencyMs = st.latencyMs\n if (latencyMs !== undefined) {\n // Same int() check the report uses for counters: latency is always a\n // non-negative whole-millisecond number; a NaN/Infinity/negative arrives\n // from a buggy host and must not silently render as `(NaNms)`.\n if (\n typeof latencyMs !== 'number' ||\n !Number.isFinite(latencyMs) ||\n !Number.isInteger(latencyMs) ||\n latencyMs < 0\n ) reject('step.latencyMs')\n }\n return {\n id,\n ok: bool(st, 'ok', 'step.ok'),\n message: str(st, 'message', 'step.message'),\n ...(typeof latencyMs === 'number' ? { latencyMs } : {}),\n }\n}\n\nfunction parseRelayTestResult(value: unknown): RelayTestResult {\n const s = rec(value, 'result')\n const overall = str(s, 'overall', 'overall')\n if (overall !== 'ok' && overall !== 'failed') reject('overall')\n const stepsRaw = s.steps\n if (!Array.isArray(stepsRaw)) reject('steps')\n return {\n url: str(s, 'url', 'url'),\n overall,\n tokenIssued: bool(s, 'tokenIssued', 'tokenIssued'),\n steps: (stepsRaw as unknown[]).map(parseRelayTestStep),\n }\n}\n\nfunction parsePushTestResult(value: unknown): PushTestResult {\n const s = rec(value, 'result')\n const transport = str(s, 'transport', 'transport')\n if (transport !== 'apns' && transport !== 'relay' && transport !== 'none') reject('transport')\n const overall = str(s, 'overall', 'overall')\n const overalls = ['sent', 'failed', 'no-targets', 'not-configured']\n if (!overalls.includes(overall)) reject('overall')\n const resultsRaw = s.results\n if (!Array.isArray(resultsRaw)) reject('results')\n const results = (resultsRaw as unknown[]).map((value) => {\n const r = rec(value, 'device result')\n const reason = r.reason\n const tokenFingerprint = r.tokenFingerprint\n return {\n name: str(r, 'name', 'result.name'),\n environment: str(r, 'environment', 'result.environment'),\n outcome: str(r, 'outcome', 'result.outcome'),\n ...(typeof reason === 'string' && reason.length > 0 ? { reason } : {}),\n ...(typeof tokenFingerprint === 'string' && /^[0-9a-f]{10}$/.test(tokenFingerprint)\n ? { tokenFingerprint }\n : {}),\n }\n })\n const message = s.message\n return {\n transport,\n overall: overall as PushTestResult['overall'],\n ...(typeof message === 'string' && message.length > 0 ? { message } : {}),\n results,\n }\n}\n\nfunction parseDiagnosticFailure(value: unknown): ReportDiagnosticFailure {\n const s = rec(value, 'diagnostics.recentFailures[]')\n // kind / reason 是代码内枚举常量;这里收敛字符集与长度,防止上游把\n // 任意文本(路径、IP、错误消息)塞进设置页。\n const kind = str(s, 'kind', 'diagnostics.kind')\n if (!/^[a-z][a-z0-9-]{0,47}$/.test(kind)) reject('diagnostics.kind')\n const reason = str(s, 'reason', 'diagnostics.reason')\n if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(reason)) reject('diagnostics.reason')\n const attemptId = s.attemptId\n if (attemptId !== undefined && (typeof attemptId !== 'string' || !/^[A-Za-z0-9_-]{1,16}$/.test(attemptId))) {\n reject('diagnostics.attemptId')\n }\n const source = s.source\n if (source !== undefined && (typeof source !== 'string' || !/^[0-9a-f]{8,64}$/.test(source))) {\n reject('diagnostics.source')\n }\n const closeCode = s.closeCode\n if (closeCode !== undefined && (typeof closeCode !== 'number' || !Number.isInteger(closeCode))) {\n reject('diagnostics.closeCode')\n }\n const durationMs = s.durationMs\n if (durationMs !== undefined && (typeof durationMs !== 'number' || !Number.isFinite(durationMs) || durationMs < 0)) {\n reject('diagnostics.durationMs')\n }\n return {\n ts: int(s, 'ts', 'diagnostics.ts'),\n kind,\n reason,\n ...(typeof attemptId === 'string' ? { attemptId } : {}),\n ...(typeof source === 'string' ? { source } : {}),\n ...(typeof closeCode === 'number' ? { closeCode } : {}),\n ...(typeof durationMs === 'number' ? { durationMs: Math.round(durationMs) } : {}),\n }\n}\n\nfunction parseDiagnostics(value: unknown): ReportDiagnostics {\n const s = rec(value, 'diagnostics')\n const failures = s.recentFailures\n if (!Array.isArray(failures)) reject('diagnostics.recentFailures')\n // 页面上是「最近失败」列表,20 条足够;硬上限防止坏 Host 撑爆 UI。\n if (failures.length > 20) reject('diagnostics.recentFailures')\n return {\n startedAt: int(s, 'startedAt', 'diagnostics.startedAt'),\n recentFailures: (failures as unknown[]).map(parseDiagnosticFailure),\n }\n}\n\nfunction parseReport(value: unknown): DeepPilotReport {\n const s = rec(value, 'report')\n const devices = s.devices\n const lanAddresses = s.lanAddresses\n if (!Array.isArray(devices)) reject('devices')\n if (!Array.isArray(lanAddresses) || lanAddresses.some((value) => typeof value !== 'string')) reject('lanAddresses')\n // Update fields are optional: an older Host (without the background\n // GitHub check) won't include them, and the UI must keep rendering.\n const releaseUrl = s.releaseUrl\n return {\n protocolVersion: int(s, 'protocolVersion', 'protocolVersion'),\n serverVersion: str(s, 'serverVersion', 'serverVersion'),\n pluginVersion: str(s, 'pluginVersion', 'pluginVersion'),\n ...(s.updateAvailable === true ? { updateAvailable: true } : {}),\n ...(typeof releaseUrl === 'string' && releaseUrl.length > 0\n ? { releaseUrl } : {}),\n enabled: bool(s, 'enabled', 'enabled'),\n identityPath: str(s, 'identityPath', 'identityPath'),\n pairingReady: bool(s, 'pairingReady', 'pairingReady'),\n activeConnections: int(s, 'activeConnections', 'activeConnections'),\n historyBufferMax: int(s, 'historyBufferMax', 'historyBufferMax'),\n lanAddresses: lanAddresses as string[],\n local: parseLocal(s.local),\n remote: parseRemote(s.remote),\n devices: (devices as unknown[]).map(parseDevice),\n // 旧 Host 没有这个字段:保持可选,设置页整块跳过。\n ...(s.diagnostics !== undefined ? { diagnostics: parseDiagnostics(s.diagnostics) } : {}),\n }\n}\n\nexport const reportSchema: TypertSchema<DeepPilotReport> = { parse: parseReport }\n\nexport const relayTestSchema: TypertSchema<RelayTestResult> = { parse: parseRelayTestResult }\n\nexport const pushTestSchema: TypertSchema<PushTestResult> = { parse: parsePushTestResult }\n\nexport const pairingGrantSchema: TypertSchema<PairingGrantSnapshot> = {\n parse(value: unknown): PairingGrantSnapshot {\n const s = rec(value, 'pairing grant')\n const code = str(s, 'code', 'pairingGrant.code')\n if (code.length < 32) reject('pairingGrant.code')\n return {\n code,\n expiresAt: int(s, 'expiresAt', 'pairingGrant.expiresAt'),\n audience: str(s, 'audience', 'pairingGrant.audience'),\n }\n },\n}\n\nconst deviceIdSchema: TypertSchema<string> = {\n parse(value: unknown): string {\n if (typeof value !== 'string' || !/^[A-Za-z0-9_-]{43}$/.test(value)) reject('deviceId')\n return value\n },\n}\n\nconst customNameSchema: TypertSchema<string | null> = {\n parse(value: unknown): string | null {\n if (value === null) return null\n if (typeof value !== 'string') reject('customName')\n const trimmed = value.trim()\n if (trimmed.length === 0 || trimmed.length > 64 || /[\\u0000-\\u001f\\u007f-\\u009f]/u.test(value)) reject('customName')\n return trimmed\n },\n}\n\nconst scopesSchema: TypertSchema<DeviceScope[]> = {\n parse(value: unknown): DeviceScope[] {\n if (!Array.isArray(value) || value.some((scope) => typeof scope !== 'string' || !DEVICE_SCOPES.includes(scope as DeviceScope))) {\n reject('scopes')\n }\n return normalizeDeviceScopes(value)\n },\n}\n\nconst booleanSchema: TypertSchema<boolean> = {\n parse(value: unknown): boolean {\n if (typeof value !== 'boolean') reject('boolean')\n return value\n },\n}\n\n/** The rc.2 Gateway materializes each strict codec through `create()`. */\nfunction strictCodec<T>(typeSymbol: string, schema: TypertSchema<T>): TypertCodec {\n return {\n mode: 'strict',\n typeSymbol,\n create: () => schema,\n }\n}\n\n/**\n * Connectivity self-test for the push relay: health probe plus (when an\n * enroll key is on file) a real enrollment round-trip. Doubles as repair —\n * a token it issues is cached by the bridge.\n */\nexport const TEST_RELAY_ENDPOINT = 'deeppilot/testRelay'\n\n/**\n * Real-delivery push test: forces one synthetic notification down the active\n * push pathway to every registered device, ignoring connected/muted filters —\n * an explicit user action must always be able to prove the pipeline works.\n */\nexport const TEST_PUSH_ENDPOINT = 'deeppilot/testPush'\n\nexport const REPORT_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${REPORT_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'report',\n invocation: { kind: 'direct' },\n parameters: [],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeepPilotReport`, reportSchema),\n}\n\nexport const BEGIN_PAIRING_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${BEGIN_PAIRING_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'beginPairing',\n invocation: { kind: 'direct' },\n parameters: [],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#PairingGrantSnapshot`, pairingGrantSchema),\n}\n\nexport const REVOKE_DEVICE_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${REVOKE_DEVICE_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'revokeDevice',\n invocation: { kind: 'direct' },\n parameters: [{\n name: 'deviceId',\n wire: 'deviceId',\n source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceId`, deviceIdSchema),\n }],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#Boolean`, booleanSchema),\n}\n\nexport const SET_DEVICE_NAME_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${SET_DEVICE_NAME_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'setDeviceName',\n invocation: { kind: 'direct' },\n parameters: [\n {\n name: 'deviceId', wire: 'deviceId', source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceId`, deviceIdSchema),\n },\n {\n name: 'customName', wire: 'customName', source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#CustomDeviceName`, customNameSchema),\n },\n ],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#CustomDeviceName`, customNameSchema),\n}\n\nexport const SET_DEVICE_SCOPES_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${SET_DEVICE_SCOPES_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'setDeviceScopes',\n invocation: { kind: 'direct' },\n parameters: [\n {\n name: 'deviceId', wire: 'deviceId', source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceId`, deviceIdSchema),\n },\n {\n name: 'scopes', wire: 'scopes', source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceScopes`, scopesSchema),\n },\n ],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceScopes`, scopesSchema),\n}\n\nexport const TEST_RELAY_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${TEST_RELAY_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'testRelay',\n invocation: { kind: 'direct' },\n parameters: [],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#RelayTestResult`, relayTestSchema),\n}\n\nexport const TEST_PUSH_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${TEST_PUSH_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'testPush',\n invocation: { kind: 'direct' },\n parameters: [],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#PushTestResult`, pushTestSchema),\n}\n\nconst INVOCATION_DESCRIPTORS = [\n REPORT_DESCRIPTOR,\n BEGIN_PAIRING_DESCRIPTOR,\n REVOKE_DEVICE_DESCRIPTOR,\n SET_DEVICE_NAME_DESCRIPTOR,\n SET_DEVICE_SCOPES_DESCRIPTOR,\n TEST_RELAY_DESCRIPTOR,\n TEST_PUSH_DESCRIPTOR,\n]\n\nexport const REPORT_HOST_CONTRIBUTION = {\n package: REPORT_REMOTE_PACKAGE,\n face: 'host' as const,\n schemas: [],\n // This hand-written Remote has no generated reflection exports.\n model: { services: [], events: [], objects: [] },\n invocations: INVOCATION_DESCRIPTORS,\n}\n\nexport const REPORT_REMOTE_CONTRIBUTION: TypertRemoteContribution = {\n package: REPORT_REMOTE_PACKAGE,\n descriptors: INVOCATION_DESCRIPTORS,\n}\n","import type { DeviceScope } from '../device-auth.ts'\nimport type { DeepPilotReport, PairingGrantSnapshot, PushTestResult, RelayTestResult } from '../report-wire.ts'\nimport { REPORT_REMOTE_CONTRIBUTION } from '../report-wire.ts'\n\nexport type RemoteResult<T> =\n | { ok: true; value: T }\n | { ok: false; error: { message?: string } }\n\nexport interface ReportRemote {\n report(): Promise<RemoteResult<DeepPilotReport>>\n beginPairing(): Promise<RemoteResult<PairingGrantSnapshot>>\n revokeDevice(deviceId: string): Promise<RemoteResult<boolean>>\n /** Optional so a newer client can degrade against an older host. */\n setDeviceName?(deviceId: string, customName: string | null): Promise<RemoteResult<string | null>>\n setDeviceScopes(deviceId: string, scopes: DeviceScope[]): Promise<RemoteResult<DeviceScope[]>>\n /** Optional so an older host never breaks a newer client (and vice versa). */\n testRelay?(): Promise<RemoteResult<RelayTestResult>>\n /** Forces one real push delivery to every registered device. */\n testPush?(): Promise<RemoteResult<PushTestResult>>\n}\n\nexport interface ClientRemoteLike {\n $mount(contribution: unknown): Promise<() => Promise<void>>\n}\n\nexport interface MountedReportRemote {\n namespace: ReportRemote\n dispose: () => Promise<void>\n}\n\n/** Mount the contribution and resolve the namespace service it installs. */\nexport async function mountReportRemote(\n remote: ClientRemoteLike,\n resolveNamespace: () => ReportRemote | undefined,\n): Promise<MountedReportRemote> {\n const dispose = await remote.$mount(REPORT_REMOTE_CONTRIBUTION)\n const namespace = resolveNamespace()\n if (namespace === undefined) {\n await dispose()\n throw new Error('remote.deeppilot 未注册')\n }\n return { namespace, dispose }\n}\n","/**\n * Internationalization for the DeepPilot settings page.\n *\n * Architecture:\n * - The DSH host shell (via dsh-client-locale) owns language switching and\n * owns the locale face every client module can register against. When\n * that face is present we forward our strings to it and look them up via\n * `ctx.locale.bind(namespace)(key)`, which is the runtime's contract.\n * - When the locale face is absent (offline build, headless test, a\n * profile that doesn't include dsh-client-locale) we still need to\n * render the page in the user's language, so the same module ships a\n * built-in fallback table keyed identically and resolves keys locally.\n * - The `t(ctx, key, vars?)` helper hides which path is in use; callers\n * always go through it. The optional second argument performs\n * `{name}`-style substitution that the host bind() does not do.\n *\n * The tables below are the source of truth; the section header comment\n * here is the place to look when adding a key. A test in\n * `tests/i18n.test.ts` walks the table to guarantee every key in zh has a\n * matching en entry and vice versa, so a partial translation trips CI.\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\n\n/** DSH runtime locale face — structural, not imported (the package is not\n * on this plugin's dependency surface). */\ninterface LocaleFace {\n register: (namespace: string, table: unknown) => () => void\n bind: (namespace: string) => (key: string, vars?: Readonly<Record<string, unknown>>) => string\n getSnapshot?: () => { active: string; revision: number }\n}\n\ninterface AnyCtx extends Context {\n locale?: LocaleFace\n}\n\n/** Single namespace shared with the host's locale registry, so other\n * host-side modules (if any) can translate the same keys. */\nexport const DEEPPILOT_LOCALE_NS = 'settings.deeppilot'\n\n/** Locale codes this module currently ships. Keep in sync with the\n * language switches the host exposes; the fallback picks `en` if a user\n * ever requests a locale we don't translate. */\nexport type SupportedLocale = 'zh' | 'en'\n\n/** Translation function injected by a locale-aware slot. */\nexport type Translate = (key: string, vars?: Readonly<Record<string, unknown>>) => string\n\ninterface LocaleTables {\n zh: Record<string, string>\n en: Record<string, string>\n}\n\n/**\n * Single source of truth. Every key here MUST have a translation in every\n * supported locale; the i18n.test.ts \"table parity\" check enforces that.\n *\n * Shape: `{ locale: { key: value } }` — the same shape `dsh-client-locale`'s\n * `register(namespace, table)` accepts (and the same shape we already used\n * at the bottom of client/index.ts before this module existed).\n *\n * Naming convention: `<section>.<field>` (two dotted segments, lowercase,\n * ASCII-only). Names longer than two segments are reserved for future\n * sub-section splits and intentionally absent today.\n */\nconst TABLES: LocaleTables = {\n zh: {\n\n // 紧凑设置页:默认仅展示连接、设备与两个工具折叠行。\n 'local.options': '局域网连接选项',\n 'remote.options': '远程连接选项',\n 'local.errorDetails': '局域网连接异常,请检查连接选项({message})。',\n 'remote.errorDetails': '远程连接异常,请检查授权与连接选项({message})。',\n 'pair.add': '添加手机',\n 'pair.close': '收起',\n 'devices.count': '{count} 台',\n 'devices.moreAria': '设备“{name}”的更多操作',\n 'tools.title': '工具与信息',\n 'diag.reportFailed': '读取连接状态失败',\n 'diagnostics.historyCount': '{count} 条历史失败记录',\n 'diagnostics.kind.upgrade': '连接请求被拒绝',\n 'diagnostics.kind.pair': '配对请求被拒绝',\n 'diagnostics.kind.auth': '设备认证失败',\n 'diagnostics.kind.opened': '连接已建立',\n 'diagnostics.kind.closed': '连接异常断开',\n 'diagnostics.kind.error': '连接发生错误',\n 'diagnostics.kind.identity': '设备身份异常',\n 'diagnostics.kind.storage': '设备信息保存失败',\n 'diagnostics.kind.unknown': '连接异常',\n 'push.outcome.sent': '已发送',\n 'push.outcome.failed': '发送失败',\n 'push.outcome.invalid': '设备推送凭据无效',\n 'push.environment.development': '开发环境',\n 'push.environment.production': '正式环境',\n 'push.environment.other': '其他环境({environment})',\n 'push.outcome.other': '推送状态({outcome})',\n 'push.resultDetail': '推送结果({message})',\n\n // ---- meta / nav ----\n 'nav': 'DeepPilot',\n 'meta.title': 'DeepPilot',\n 'meta.intro': '在手机上使用这台电脑的 DSH。',\n 'meta.refresh': '刷新',\n\n // ---- master switch ----\n 'master.title': '允许手机连接',\n 'master.loading': '正在读取配置…',\n 'master.on': '已开启:接受手机连接。',\n 'master.off': '已关闭:不接受手机连接。',\n\n // ---- compact page hierarchy ----\n 'status.loading': '正在读取状态…',\n 'status.off': '未启用',\n 'status.ready': '服务已就绪',\n 'status.attention': '需要处理',\n 'connection.title': '连接',\n 'connection.description': '控制手机可用的局域网与公网连接。',\n 'connection.optionsSummary': '连接选项',\n 'pair.description': '选择连接方式并生成一次性配对信息。',\n 'devices.description': '管理已经配对的 iPhone。',\n 'troubleshooting.summary': '诊断工具',\n 'troubleshooting.title': '诊断工具',\n 'troubleshooting.description': '仅在排查连接或推送问题时使用。',\n 'troubleshooting.debugTitle': '调试日志',\n 'troubleshooting.debugDescription': '开启后,新的手机连接会在 DSH 终端输出诊断日志;已连接手机需重连后生效。日志不包含配对码、推送凭据或消息内容。',\n // ---- 连接诊断(P0:最近失败可观测) ----\n 'diagnostics.title': '连接诊断',\n 'diagnostics.description': '最近的连接失败事件;可一键复制后发给维护者排查。',\n 'diagnostics.recent': '最近失败',\n 'diagnostics.empty': '最近没有失败记录',\n 'diagnostics.staleHost': '宿主插件版本较旧,没有连接诊断数据,请更新 dsh-deeppilot。',\n 'diagnostics.copy': '复制诊断信息',\n 'diagnostics.copied': '诊断信息已复制',\n 'diagnostics.copyFailed': '复制诊断信息失败:',\n 'diagnostics.item': '{time} · {kind} · {reason}',\n 'diagnostics.attempt': '尝试 {id}',\n 'diagnostics.source': '来源 {label}',\n 'diagnostics.closeCode': '关闭码 {code}',\n 'diagnostics.duration': '耗时 {ms}ms',\n 'diagnostics.startedAt': '启动于 {time}',\n 'diagnostics.reportTitle': 'DeepPilot 诊断信息',\n 'diagnostics.reportGeneratedAt': '生成时间',\n 'diagnostics.reportVersion': '插件版本',\n 'diagnostics.reportEnabled': '总开关',\n 'diagnostics.reportLocal': '局域网',\n 'diagnostics.reportRemote': '公网',\n 'diagnostics.reportConnections': '当前连接',\n 'diagnostics.reportFailureHeader': '最近失败',\n 'diagnostics.reportNone': '(无)',\n 'diagnostics.on': '已启用',\n 'diagnostics.off': '已关闭',\n 'system.summary': '系统信息',\n 'system.title': '运行信息',\n 'system.description': '插件、协议与连接端点的技术信息。',\n\n // ---- local connection ----\n 'local.title': '局域网连接',\n 'local.on': '已开启:手机可通过独立端口 {port} 以 TLS 加密连接。',\n 'local.off': '已关闭:不接受局域网连接。',\n 'local.tlsFingerprint': '证书指纹',\n 'local.tlsRegenerated': '局域网 TLS 身份已重新生成:此前通过内网配对的设备需要重新扫码配对。',\n 'local.phaseDisabled': '局域网连接未启用',\n 'local.phaseStarting': '局域网连接正在启动',\n 'local.phaseOnline': '局域网连接已就绪',\n 'local.phaseError': '局域网连接失败',\n 'local.phaseStopped': '局域网连接已停止',\n 'local.portTitle': '局域网端口',\n 'local.portDescription': '默认 3098,范围 1024–65535。该端口只以 TLS 提供 DeepPilot 的三个连接端点,不会开放完整 DSH。',\n 'local.portApplied': '局域网端口已保存,监听器正在重新加载。',\n 'local.portInvalid': '请输入 1024–65535 之间的整数。',\n 'local.portFailed': '局域网端口保存失败:',\n\n // ---- remote switch (Tailscale Funnel) ----\n 'remote.title': '远程连接',\n 'remote.on': '已配置:内嵌 Funnel 会自动启动并同步状态。',\n 'remote.off': '关闭:仅保留局域网连接。',\n 'remote.openAuth': '打开授权页面',\n 'remote.advancedSettings': '高级设置',\n 'remote.limitTitle': '每个公网来源的连接上限',\n 'remote.limitDescription': '默认 8,范围 1–16。应用后 Funnel 会重启,已有远程连接将短暂重连。',\n 'remote.limitApply': '应用',\n 'remote.limitApplied': '连接上限已保存,远程入口正在重新加载。',\n 'remote.limitInvalid': '请输入 1–16 之间的整数。',\n 'remote.limitFailed': '连接上限保存失败:',\n\n // ---- remote phases ----\n 'phase.disabled': '未启用',\n 'phase.starting': '正在启动',\n 'phase.login_required': '等待 Tailscale 授权',\n 'phase.online': '远程连接已就绪',\n 'phase.error': '远程连接失败',\n 'phase.unavailable': '远程 helper 不可用',\n 'phase.stopped': '已停止',\n 'phase.unknown': '状态未知',\n\n // ---- short channel states shown beside each switch ----\n 'channel.state.disabled': '未启用',\n 'channel.state.starting': '正在启动',\n 'channel.state.login_required': '待授权',\n 'channel.state.online': '已就绪',\n 'channel.state.error': '失败',\n 'channel.state.unavailable': '不可用',\n 'channel.state.stopped': '已停止',\n\n // ---- connection panel ----\n 'panel.activeConnections': '当前连接',\n 'panel.identity': '设备身份认证',\n 'panel.identityReady': 'v2 已就绪',\n 'panel.identityNotReady': '不可用',\n 'panel.token': '配对 Token',\n 'panel.tokenReady': '已就绪',\n 'panel.tokenNotReady': '未生成',\n 'panel.tokenMasked': '••••••••••••',\n 'panel.tokenAction.show': '显示',\n 'panel.tokenAction.hide': '隐藏',\n 'panel.tokenAction.copy': '复制',\n 'panel.tokenAction.rotate': '更换',\n 'panel.tokenAction.rotateConfirm': '确认更换?',\n 'panel.tokenAction.showing': '读取中…',\n 'panel.tokenAction.rotating': '更换中…',\n 'panel.tokenAutoHidden': 'Token 已自动隐藏',\n 'panel.tokenCopied': '已复制到剪贴板',\n 'panel.tokenCopyFailed': '复制失败:',\n 'panel.tokenRevealFailed': 'Token 读取失败:',\n 'panel.tokenRotateWarning': '更换会使当前 Token 立即失效、断开所有手机连接;5 秒内再次点击确认。',\n 'panel.tokenRotated': '新 Token 已生效,旧 Token 已失效;请重新配对所有设备。',\n 'panel.tokenRotateFailed': '更换失败:',\n\n // ---- pairing QR ----\n 'pair.qrPanelTitle': '添加手机',\n 'pair.kind.public': '公网',\n 'pair.kind.lan': '内网',\n 'pair.noAddress': '没有可用地址',\n 'pair.noAddressHelp': '没有可用的局域网或远程入口。请确认局域网连接已启动,或启用远程连接。',\n 'pair.disabledHelp': '请先开启“允许手机连接”,再添加手机。',\n 'pair.qrAlt': 'DeepPilot 配对二维码',\n 'pair.qrShow': '显示二维码',\n 'pair.qrHide': '隐藏二维码',\n 'pair.qrGenerating': '生成中…',\n 'pair.qrExpired': '配对码已过期,请重新显示二维码',\n 'pair.qrFailed': '二维码生成失败:',\n 'pair.qrRetry': '重试',\n 'pair.infoLabel': '配对信息(复制一次,粘贴到 App 即可)',\n 'pair.infoCopyDone': '配对信息已复制',\n 'pair.infoCopyFailed': '配对信息复制失败:',\n // `{kind}`: public | lan\n 'pair.qrHint': '二维码与「配对信息」内容相同:包含{kind}地址、一次性配对码、证书指纹(内网时)与主机标识。在局域网与公网之间切换会立即生成对应的新配对信息,配对码 5 分钟后失效。',\n\n // ---- advanced info ----\n 'advanced.summary': '高级信息',\n 'advanced.protocolVersion': '协议版本',\n 'advanced.serverVersion': '服务器版本',\n // 内嵌 Funnel helper 自报的 tailscale.com 版本;未上报时显示未获取。\n 'advanced.tailscaleVersion': 'Tailscale 版本',\n 'advanced.tailscaleVersionUnknown': '未获取',\n 'advanced.tokenPath': 'Token 路径',\n 'advanced.identityPath': '设备注册表路径',\n 'advanced.bufferMax': '重放缓冲上限',\n 'advanced.frames': ' 帧',\n\n // ---- push tests ----\n 'push.relayTitle': '离线推送中继',\n 'push.testRelay': '测试访问与注册',\n 'push.testPush': '发送测试通知',\n 'push.relayTesting': '测试中…',\n 'push.pushSending': '发送中…',\n 'push.relayDefault': '验证这台电脑到推送中继的连通性与自动注册是否正常。',\n 'push.pushDefault': '向所有已注册设备强制发送一条真实推送(不受在线状态与分类开关影响)。',\n 'push.relayOk': '通过',\n 'push.relayBad': '存在问题',\n 'push.relayUrlEmpty': '(未启用)',\n 'push.pushSent': '已送达',\n 'push.pushFailed': '发送失败',\n 'push.pushNoTargets': '无已注册设备',\n 'push.pushNotEnabled': '推送未启用',\n 'push.relayStep.health': '服务可达',\n 'push.relayStep.enroll': '自动注册',\n 'push.prefix.ok': '通过:',\n 'push.prefix.fail': '未通过:',\n\n // ---- devices table ----\n 'devices.title': '已配对设备',\n 'devices.col.name': '设备',\n 'devices.col.appVersion': 'App 版本',\n 'devices.col.push': '离线推送',\n 'devices.col.lastSeen': '最近在线',\n 'devices.col.fingerprint': '密钥指纹',\n 'devices.col.actions': '操作',\n 'devices.rename': '重命名',\n 'devices.renameAria': '重命名设备“{name}”',\n 'devices.nameLabel': '设备名称',\n 'devices.namePlaceholder': '例如:工作手机',\n 'devices.nameSave': '保存',\n 'devices.nameCancel': '取消',\n 'devices.nameSaving': '保存中…',\n 'devices.nameInvalid': '设备名称不能超过 64 个字符。',\n 'devices.customBadge': '自定义',\n 'devices.unnamed': '未命名设备',\n 'devices.renamed': '设备名称已保存',\n 'devices.nameCleared': '已恢复设备默认名称',\n 'devices.renameFailed': '设备名称保存失败:',\n 'devices.renameStaleHost': '宿主插件版本较旧,不支持设备重命名 — 请更新 dsh-deeppilot',\n 'devices.revoke': '删除',\n 'devices.revokeAria': '删除设备“{name}”',\n 'devices.deleting': '删除中…',\n 'devices.revokeConfirm': '确定删除设备“{name}”吗?该设备会立即断开,再次使用时需要重新配对。',\n 'devices.revoked': '设备已删除',\n 'devices.revokeFailed': '设备删除失败:',\n 'devices.pushRegistered': '已注册(',\n 'devices.pushNotRegistered': '未注册',\n 'devices.pushEnvProduction': '生产',\n 'devices.pushEnvDevelopment': '开发',\n 'devices.empty': '还没有配对设备。点击“添加手机”,然后在 DeepPilot 中扫码连接。',\n\n // ---- remote help ----\n 'help.remoteTitle': '远程连接帮助',\n 'help.recommended': '推荐设置流程',\n 'help.step1': '先打开“允许手机连接”,再打开“远程连接”。',\n 'help.step2': '状态变为\"等待 Tailscale 授权\"后,点击\"打开授权页面\"。',\n 'help.step3': '使用有权管理此 Tailnet 的账号登录,并按授权页提示启用 Funnel。通常需要 Owner、Admin 或 Network admin 权限。',\n 'help.step4': '返回此页面并点击“刷新”。远程连接显示“已就绪”后,点击“添加手机”并扫码。',\n 'help.funnelHint': '插件已内嵌 Tailscale 网络组件,这台电脑和手机都不需要另外安装 Tailscale App;但首次启用仍需由 Tailnet 管理员授权。',\n 'help.httpsTitle': '授权页未自动完成时:开启 HTTPS',\n 'help.httpsStep1': '打开 Tailscale 管理后台的 Network → DNS。',\n 'help.httpsStep2': '确认 MagicDNS 已开启。',\n 'help.httpsStep3': '在 HTTPS Certificates 中点击 Enable HTTPS。',\n 'help.httpsHint': '启用 HTTPS 后,设备的完整域名会写入公开的证书透明度日志。如果设备名包含敏感信息,请先在 Tailscale 中重命名设备。',\n 'help.allowTitle': '授权页未自动完成时:允许 Funnel',\n 'help.allowBody': '打开 Access controls → Definitions,选择 Node attributes。在现有 nodeAttrs 数组中追加下面这一项;不要覆盖已有访问规则,也不要创建第二个 nodeAttrs 顶层字段。',\n 'help.allowHint': '保存策略后回到本页刷新。公共 DNS 和权限变更可能需要几分钟生效。',\n 'help.faqTitle': '常见问题',\n 'help.faq1': '提示\"HTTPS must be enabled\":完成上面的 HTTPS Certificates 设置。',\n 'help.faq2': '\"Funnel not available\":确认 nodeAttrs 已保存,并且当前节点属于规则的 target。',\n 'help.faq3': '已有公网地址但手机超时:等待几分钟后重试,同时确认这台电脑未休眠、DSH 正在运行,再重新扫描最新二维码。',\n 'help.faq4': '没有公网地址:检查 Tailscale 授权是否完成,然后点击\"刷新\"或重启 DSH。',\n 'help.securityTitle': '安全说明',\n 'help.security1': 'Funnel 公网地址可从互联网访问,但连接必须使用已配对设备的 P-256 私钥签名;不要分享仍在有效期内的配对二维码。',\n 'help.security2': '丢失设备时可在设备列表中单独删除;该设备会立即断开,不影响其他手机。',\n 'help.security3': 'Funnel 和局域网监听器都只提供 /phone、/phone/pair 和 /phone/health,不会暴露完整 DSH Web/API。',\n 'help.security4': '局域网连接使用插件独立的 3098 端口并启用 TLS。只在可信网络中使用,不要把该端口转发到公网。',\n 'help.security5': '关闭远程连接开关会停止 Funnel,但不会影响可用的局域网连接。',\n 'help.funnelDocs': 'Tailscale Funnel 官方文档',\n 'help.docsPrefix': '更多信息:',\n\n // ---- diagnostic line (visible when something is missing) ----\n 'diag.summary': '技术诊断',\n 'diag.remoteUnavailable': 'remote 服务不可用',\n 'diag.remoteUnmounted': 'report remote 未挂载',\n 'diag.mountFailed': '报告远程未挂载(remote mount 失败)— 请确认宿主包含 typert 组合',\n 'diag.mountFailedShort': 'remote mount 失败: ',\n 'diag.callFailed': 'report remote 调用失败',\n 'diag.settingsUnavailable': '设置表单不可用(configForms 未提供)',\n 'diag.missingReportHook': 'useDeepPilotReport hook 缺失',\n 'diag.missingEnabledHook': 'useDeepPilotEnabled hook 缺失',\n 'diag.missingLocalEnabledHook': 'useDeepPilotLocalEnabled hook 缺失',\n 'diag.missingLocalPortHook': 'useDeepPilotLocalPort hook 缺失',\n 'diag.missingRemoteEnabledHook': 'useDeepPilotRemoteEnabled hook 缺失',\n 'diag.missingRemoteLimitHook': 'useDeepPilotRemoteConnectionLimit hook 缺失',\n 'diag.missingDebugHook': 'useDeepPilotDebug hook 缺失',\n 'diag.missingRefresh': 'refresh 回调缺失',\n 'diag.missingReveal': 'beginPairing 回调缺失',\n 'diag.missingRotate': 'revokeDevice 回调缺失',\n 'diag.missingRename': 'setDeviceName 回调缺失',\n 'diag.missingTestRelay': 'testRelay 回调缺失',\n 'diag.missingTestPush': 'testPush 回调缺失',\n 'diag.missingSetEnabled': 'setDeepPilotEnabled 回调缺失',\n 'diag.missingSetLocal': 'setDeepPilotLocalEnabled 回调缺失',\n 'diag.missingSetLocalPort': 'setDeepPilotLocalPort 回调缺失',\n 'diag.missingSetRemote': 'setDeepPilotRemoteEnabled 回调缺失',\n 'diag.missingSetRemoteLimit': 'setDeepPilotRemoteConnectionLimit 回调缺失',\n 'diag.missingSetDebug': 'setDeepPilotDebug 回调缺失',\n 'diag.renderError': '渲染异常: ',\n 'diag.prefix': 'diag: ',\n\n // ---- clipboard fallback error (unrelated to user action) ----\n 'clipboard.rejected': '浏览器拒绝了剪贴板写入',\n\n // ---- push test edge cases (server-side messages the UI surfaces verbatim) ----\n 'push.staleHost': '宿主插件版本较旧,不支持推送测试',\n 'push.staleHostRelay': '宿主插件版本较旧,不支持中继测试',\n 'push.staleHostPush': '宿主插件版本较旧,不支持推送测试 — 请更新 dsh-deeppilot',\n 'push.staleHostPushRelay': '宿主插件版本较旧,不支持中继测试 — 请更新 dsh-deeppilot',\n\n // ---- update checker ----\n 'update.badge': '有新版本',\n },\n\n en: {\n\n // Compact settings surface.\n 'local.options': 'LAN connection options',\n 'remote.options': 'Remote connection options',\n 'local.errorDetails': 'LAN connection failed. Check the connection options ({message}).',\n 'remote.errorDetails': 'Remote connection failed. Check authorization and connection options ({message}).',\n 'pair.add': 'Add phone',\n 'pair.close': 'Collapse',\n 'devices.count': '{count} devices',\n 'devices.moreAria': 'More actions for “{name}”',\n 'tools.title': 'Tools and information',\n 'diag.reportFailed': 'Failed to read connection status',\n 'diagnostics.historyCount': '{count} past failures',\n 'diagnostics.kind.upgrade': 'Connection request rejected',\n 'diagnostics.kind.pair': 'Pairing request rejected',\n 'diagnostics.kind.auth': 'Device authentication failed',\n 'diagnostics.kind.opened': 'Connection opened',\n 'diagnostics.kind.closed': 'Connection closed unexpectedly',\n 'diagnostics.kind.error': 'Connection error',\n 'diagnostics.kind.identity': 'Device identity error',\n 'diagnostics.kind.storage': 'Saving device information failed',\n 'diagnostics.kind.unknown': 'Connection problem',\n 'push.outcome.sent': 'Sent',\n 'push.outcome.failed': 'Failed to send',\n 'push.outcome.invalid': 'Invalid push credentials',\n 'push.environment.development': 'Development',\n 'push.environment.production': 'Production',\n 'push.environment.other': 'Other environment ({environment})',\n 'push.outcome.other': 'Push status ({outcome})',\n 'push.resultDetail': 'Push result ({message})',\n\n // ---- meta / nav ----\n 'nav': 'DeepPilot',\n 'meta.title': 'DeepPilot',\n 'meta.intro': 'Use this computer’s DSH from your phone.',\n 'meta.refresh': 'Refresh',\n\n // ---- master switch ----\n 'master.title': 'Allow phone connections',\n 'master.loading': 'Loading settings…',\n 'master.on': 'On: accepting phone connections.',\n 'master.off': 'Off: not accepting phone connections.',\n\n // ---- compact page hierarchy ----\n 'status.loading': 'Loading status…',\n 'status.off': 'Disabled',\n 'status.ready': 'Service ready',\n 'status.attention': 'Needs attention',\n 'connection.title': 'Connections',\n 'connection.description': 'Control the LAN and public connections available to your phone.',\n 'connection.optionsSummary': 'Connection options',\n 'pair.description': 'Choose a connection type and generate one-time pairing information.',\n 'devices.description': 'Manage iPhones that are already paired.',\n 'troubleshooting.summary': 'Diagnostic tools',\n 'troubleshooting.title': 'Diagnostic tools',\n 'troubleshooting.description': 'Use these only when diagnosing connection or push issues.',\n 'troubleshooting.debugTitle': 'Debug logging',\n 'troubleshooting.debugDescription': 'New phone connections write diagnostic logs to the DSH terminal. Connected phones must reconnect to pick up the change. Logs exclude pairing codes, push credentials, and message content.',\n // ---- connection diagnostics (P0: observable failures) ----\n 'diagnostics.title': 'Connection diagnostics',\n 'diagnostics.description': 'Recent connection failures; copy them for troubleshooting.',\n 'diagnostics.recent': 'Recent failures',\n 'diagnostics.empty': 'No recent failures',\n 'diagnostics.staleHost': 'This host is too old to report connection diagnostics. Update dsh-deeppilot.',\n 'diagnostics.copy': 'Copy diagnostics',\n 'diagnostics.copied': 'Diagnostics copied',\n 'diagnostics.copyFailed': 'Copying diagnostics failed: ',\n 'diagnostics.item': '{time} · {kind} · {reason}',\n 'diagnostics.attempt': 'attempt {id}',\n 'diagnostics.source': 'source {label}',\n 'diagnostics.closeCode': 'close code {code}',\n 'diagnostics.duration': '{ms}ms',\n 'diagnostics.startedAt': 'Started {time}',\n 'diagnostics.reportTitle': 'DeepPilot diagnostics',\n 'diagnostics.reportGeneratedAt': 'Generated',\n 'diagnostics.reportVersion': 'Plugin version',\n 'diagnostics.reportEnabled': 'Master switch',\n 'diagnostics.reportLocal': 'LAN',\n 'diagnostics.reportRemote': 'Funnel',\n 'diagnostics.reportConnections': 'Active connections',\n 'diagnostics.reportFailureHeader': 'Recent failures',\n 'diagnostics.reportNone': '(none)',\n 'diagnostics.on': 'enabled',\n 'diagnostics.off': 'disabled',\n 'system.summary': 'System information',\n 'system.title': 'Runtime information',\n 'system.description': 'Technical details about the plugin, protocol, and endpoints.',\n\n // ---- local connection ----\n 'local.title': 'LAN connection',\n 'local.on': 'On: phones connect over TLS through the independent port {port}.',\n 'local.off': 'Off: LAN connections are not accepted.',\n 'local.tlsFingerprint': 'Certificate fingerprint',\n 'local.tlsRegenerated': 'The LAN TLS identity was regenerated: devices previously paired over LAN must scan a new pairing QR.',\n 'local.phaseDisabled': 'LAN connection disabled',\n 'local.phaseStarting': 'LAN connection starting',\n 'local.phaseOnline': 'LAN connection ready',\n 'local.phaseError': 'LAN connection failed',\n 'local.phaseStopped': 'LAN connection stopped',\n 'local.portTitle': 'LAN port',\n 'local.portDescription': 'Default 3098; range 1024–65535. This port serves only the three DeepPilot endpoints over TLS, never the full DSH server.',\n 'local.portApplied': 'LAN port saved; the listener is reloading.',\n 'local.portInvalid': 'Enter an integer from 1024 to 65535.',\n 'local.portFailed': 'Failed to save LAN port: ',\n\n // ---- remote switch (Tailscale Funnel) ----\n 'remote.title': 'Remote connection',\n 'remote.on': 'Configured: the embedded Funnel will start and sync state automatically.',\n 'remote.off': 'Off: LAN connections only.',\n 'remote.openAuth': 'Open authorization page',\n 'remote.advancedSettings': 'Advanced settings',\n 'remote.limitTitle': 'Connections per public source',\n 'remote.limitDescription': 'Default 8; range 1–16. Applying restarts Funnel and briefly reconnects existing remote clients.',\n 'remote.limitApply': 'Apply',\n 'remote.limitApplied': 'Connection limit saved; the remote endpoint is reloading.',\n 'remote.limitInvalid': 'Enter an integer from 1 to 16.',\n 'remote.limitFailed': 'Failed to save connection limit: ',\n\n // ---- remote phases ----\n 'phase.disabled': 'Disabled',\n 'phase.starting': 'Starting',\n 'phase.login_required': 'Awaiting Tailscale authorization',\n 'phase.online': 'Remote connection ready',\n 'phase.error': 'Remote connection failed',\n 'phase.unavailable': 'Remote helper unavailable',\n 'phase.stopped': 'Stopped',\n 'phase.unknown': 'Status unknown',\n\n // ---- short channel states shown beside each switch ----\n 'channel.state.disabled': 'Off',\n 'channel.state.starting': 'Starting',\n 'channel.state.login_required': 'Needs sign-in',\n 'channel.state.online': 'Ready',\n 'channel.state.error': 'Failed',\n 'channel.state.unavailable': 'Unavailable',\n 'channel.state.stopped': 'Stopped',\n\n // ---- connection panel ----\n 'panel.activeConnections': 'Active connections',\n 'panel.identity': 'Device authentication',\n 'panel.identityReady': 'v2 ready',\n 'panel.identityNotReady': 'Unavailable',\n 'panel.token': 'Pairing token',\n 'panel.tokenReady': 'Ready',\n 'panel.tokenNotReady': 'Not generated',\n 'panel.tokenMasked': '••••••••••••',\n 'panel.tokenAction.show': 'Show',\n 'panel.tokenAction.hide': 'Hide',\n 'panel.tokenAction.copy': 'Copy',\n 'panel.tokenAction.rotate': 'Rotate',\n 'panel.tokenAction.rotateConfirm': 'Confirm rotate?',\n 'panel.tokenAction.showing': 'Reading…',\n 'panel.tokenAction.rotating': 'Rotating…',\n 'panel.tokenAutoHidden': 'Token auto-hidden',\n 'panel.tokenCopied': 'Copied to clipboard',\n 'panel.tokenCopyFailed': 'Copy failed: ',\n 'panel.tokenRevealFailed': 'Token reveal failed: ',\n 'panel.tokenRotateWarning': 'Rotation invalidates the current token immediately and drops every paired phone. Click again within 5s to confirm.',\n 'panel.tokenRotated': 'New token active, old token invalidated. Please re-pair every device.',\n 'panel.tokenRotateFailed': 'Rotation failed: ',\n\n // ---- pairing QR ----\n 'pair.qrPanelTitle': 'Add phone',\n 'pair.kind.public': 'Public',\n 'pair.kind.lan': 'LAN',\n 'pair.noAddress': 'No address available',\n 'pair.noAddressHelp': 'No LAN or remote endpoint is available. Make sure LAN is running or enable remote access.',\n 'pair.disabledHelp': 'Turn on “Allow phone connections” before adding a phone.',\n 'pair.qrAlt': 'DeepPilot pairing QR code',\n 'pair.qrShow': 'Show QR code',\n 'pair.qrHide': 'Hide QR code',\n 'pair.qrGenerating': 'Generating…',\n 'pair.qrExpired': 'Pairing code expired — show the QR code again',\n 'pair.qrFailed': 'QR generation failed: ',\n 'pair.qrRetry': 'Retry',\n 'pair.infoLabel': 'Pairing info (copy once, paste it in the app)',\n 'pair.infoCopyDone': 'Pairing info copied',\n 'pair.infoCopyFailed': 'Failed to copy pairing info: ',\n 'pair.qrHint': 'The QR code and the pairing info carry the same {kind} address, single-use code, certificate fingerprint (for LAN) and host identity. Switching between LAN and public issues a matching new string immediately; the code expires after 5 minutes.',\n\n // ---- advanced info ----\n 'advanced.summary': 'Advanced info',\n 'advanced.protocolVersion': 'Protocol version',\n 'advanced.serverVersion': 'Server version',\n 'advanced.tailscaleVersion': 'Tailscale version',\n 'advanced.tailscaleVersionUnknown': 'Not reported',\n 'advanced.tokenPath': 'Token path',\n 'advanced.identityPath': 'Device registry path',\n 'advanced.bufferMax': 'Replay buffer cap',\n 'advanced.frames': ' frames',\n\n // ---- push tests ----\n 'push.relayTitle': 'Offline push relay',\n 'push.testRelay': 'Test reach & enroll',\n 'push.testPush': 'Send test notification',\n 'push.relayTesting': 'Testing…',\n 'push.pushSending': 'Sending…',\n 'push.relayDefault': 'Verify this computer → push relay connectivity and zero-touch enrollment.',\n 'push.pushDefault': 'Force one real push to every registered device (ignores online state and category switches).',\n 'push.relayOk': 'OK',\n 'push.relayBad': 'Issues found',\n 'push.relayUrlEmpty': '(disabled)',\n 'push.pushSent': 'Delivered',\n 'push.pushFailed': 'Send failed',\n 'push.pushNoTargets': 'No registered devices',\n 'push.pushNotEnabled': 'Push not enabled',\n 'push.relayStep.health': 'Service reachable',\n 'push.relayStep.enroll': 'Auto enrollment',\n 'push.prefix.ok': 'Passed: ',\n 'push.prefix.fail': 'Failed: ',\n\n // ---- devices table ----\n 'devices.title': 'Paired devices',\n 'devices.col.name': 'Device',\n 'devices.col.appVersion': 'App version',\n 'devices.col.push': 'Push',\n 'devices.col.lastSeen': 'Last seen',\n 'devices.col.fingerprint': 'Key fingerprint',\n 'devices.col.actions': 'Actions',\n 'devices.rename': 'Rename',\n 'devices.renameAria': 'Rename device “{name}”',\n 'devices.nameLabel': 'Device name',\n 'devices.namePlaceholder': 'For example: Work phone',\n 'devices.nameSave': 'Save',\n 'devices.nameCancel': 'Cancel',\n 'devices.nameSaving': 'Saving…',\n 'devices.nameInvalid': 'Device names cannot exceed 64 characters.',\n 'devices.customBadge': 'Custom',\n 'devices.unnamed': 'Unnamed device',\n 'devices.renamed': 'Device name saved',\n 'devices.nameCleared': 'Restored the device default name',\n 'devices.renameFailed': 'Failed to save device name: ',\n 'devices.renameStaleHost': 'The host plugin is too old to rename devices — please update dsh-deeppilot',\n 'devices.revoke': 'Delete',\n 'devices.revokeAria': 'Delete device “{name}”',\n 'devices.deleting': 'Deleting…',\n 'devices.revokeConfirm': 'Delete “{name}”? It will disconnect immediately and must pair again before reconnecting.',\n 'devices.revoked': 'Device deleted',\n 'devices.revokeFailed': 'Failed to delete device: ',\n 'devices.pushRegistered': 'Registered (',\n 'devices.pushNotRegistered': 'Not registered',\n 'devices.pushEnvProduction': 'Production',\n 'devices.pushEnvDevelopment': 'Development',\n 'devices.empty': 'No paired devices yet. Click “Add phone”, then scan the QR code in DeepPilot.',\n\n // ---- remote help ----\n 'help.remoteTitle': 'Remote connection help',\n 'help.recommended': 'Recommended setup',\n 'help.step1': 'Turn on “Allow phone connections”, then “Remote connection”.',\n 'help.step2': 'When the status shows \"Awaiting Tailscale authorization\", click \"Open authorization page\".',\n 'help.step3': 'Sign in with an account that can manage this Tailnet and follow the on-page prompts to enable Funnel. Owner / Admin / Network admin is usually required.',\n 'help.step4': 'Return and click “Refresh”. Once the remote connection is ready, click “Add phone” and scan the QR code.',\n 'help.funnelHint': 'The plugin bundles the Tailscale networking stack, so neither this computer nor the phone needs the Tailscale app — but a Tailnet administrator must approve first-time use.',\n 'help.httpsTitle': 'If authorization does not complete: enable HTTPS',\n 'help.httpsStep1': 'Open the Tailscale admin console → Network → DNS.',\n 'help.httpsStep2': 'Confirm MagicDNS is enabled.',\n 'help.httpsStep3': 'In HTTPS Certificates click Enable HTTPS.',\n 'help.httpsHint': 'Enabling HTTPS publishes the device hostname to public certificate transparency logs. Rename the device in Tailscale first if its name is sensitive.',\n 'help.allowTitle': 'If authorization does not complete: allow Funnel',\n 'help.allowBody': 'Open Access controls → Definitions, select Node attributes. Append the snippet below to your existing nodeAttrs array; do not overwrite other access rules and do not add a second top-level nodeAttrs field.',\n 'help.allowHint': 'Save the policy and refresh this page. Public DNS and policy changes can take a few minutes to propagate.',\n 'help.faqTitle': 'Frequently asked questions',\n 'help.faq1': '\"HTTPS must be enabled\" — finish the HTTPS Certificates steps above.',\n 'help.faq2': '\"Funnel not available\" — make sure the nodeAttrs snippet is saved and this node is in the rule\\'s target.',\n 'help.faq3': 'Public URL exists but the phone times out: wait a few minutes, confirm the computer is awake and DSH is running, then re-scan the latest QR code.',\n 'help.faq4': 'No public URL: check that Tailscale authorization completed, then click \"Refresh\" or restart DSH.',\n 'help.securityTitle': 'Security notes',\n 'help.security1': 'A Funnel URL is public, but every connection requires a signature from a paired device P-256 private key. Do not share a pairing QR while it is valid.',\n 'help.security2': 'If a device is lost, delete only that device from the list. It disconnects immediately; other phones stay paired.',\n 'help.security3': 'Funnel and the LAN listener expose only /phone, /phone/pair, and /phone/health, never the full DSH Web/API surface.',\n 'help.security4': 'LAN uses the plugin\\'s independent port 3098 with TLS enabled. Use trusted networks only and never forward that port to the public Internet.',\n 'help.security5': 'Disabling the remote switch stops Funnel but does not affect any LAN connection you already have.',\n 'help.funnelDocs': 'Tailscale Funnel docs',\n 'help.docsPrefix': 'More info: ',\n\n // ---- diagnostic line (visible when something is missing) ----\n 'diag.summary': 'Technical diagnostics',\n 'diag.remoteUnavailable': 'remote service unavailable',\n 'diag.remoteUnmounted': 'report remote not mounted',\n 'diag.mountFailed': 'Report remote not mounted (mount failed) — confirm the host includes the typert composition',\n 'diag.mountFailedShort': 'remote mount failed: ',\n 'diag.callFailed': 'report remote call failed',\n 'diag.settingsUnavailable': 'Settings form unavailable (configForms not provided)',\n 'diag.missingReportHook': 'useDeepPilotReport hook missing',\n 'diag.missingEnabledHook': 'useDeepPilotEnabled hook missing',\n 'diag.missingLocalEnabledHook': 'useDeepPilotLocalEnabled hook missing',\n 'diag.missingLocalPortHook': 'useDeepPilotLocalPort hook missing',\n 'diag.missingRemoteEnabledHook': 'useDeepPilotRemoteEnabled hook missing',\n 'diag.missingRemoteLimitHook': 'useDeepPilotRemoteConnectionLimit hook missing',\n 'diag.missingDebugHook': 'useDeepPilotDebug hook missing',\n 'diag.missingRefresh': 'refresh callback missing',\n 'diag.missingReveal': 'beginPairing callback missing',\n 'diag.missingRotate': 'revokeDevice callback missing',\n 'diag.missingRename': 'setDeviceName callback missing',\n 'diag.missingTestRelay': 'testRelay callback missing',\n 'diag.missingTestPush': 'testPush callback missing',\n 'diag.missingSetEnabled': 'setDeepPilotEnabled callback missing',\n 'diag.missingSetLocal': 'setDeepPilotLocalEnabled callback missing',\n 'diag.missingSetLocalPort': 'setDeepPilotLocalPort callback missing',\n 'diag.missingSetRemote': 'setDeepPilotRemoteEnabled callback missing',\n 'diag.missingSetRemoteLimit': 'setDeepPilotRemoteConnectionLimit callback missing',\n 'diag.missingSetDebug': 'setDeepPilotDebug callback missing',\n 'diag.renderError': 'Render error: ',\n 'diag.prefix': 'diag: ',\n\n // ---- clipboard fallback error (unrelated to user action) ----\n 'clipboard.rejected': 'Clipboard write rejected by the browser',\n\n // ---- push test edge cases (server-side messages the UI surfaces verbatim) ----\n 'push.staleHost': 'Host plugin is too old for push testing',\n 'push.staleHostRelay': 'Host plugin is too old for relay testing',\n 'push.staleHostPush': 'Host plugin is too old for push testing — please update dsh-deeppilot',\n 'push.staleHostPushRelay': 'Host plugin is too old for relay testing — please update dsh-deeppilot',\n\n // ---- update checker ----\n 'update.badge': 'New version available',\n },\n}\n\nconst ALL_KEYS: ReadonlyArray<string> = Object.keys(TABLES.zh)\n/** Throw-on-missing helper, used by tests and as a last-ditch fallback in\n * `t()`. Kept exported so the parity test can walk the entire namespace. */\nexport function translateOrThrow(\n locale: SupportedLocale,\n key: string,\n): string {\n const value = TABLES[locale][key]\n if (value === undefined) {\n throw new Error(`i18n: missing key \"${key}\" in ${locale} table`)\n }\n return value\n}\n\n/** Substitute every `{name}` in `template` with `String(vars[name])`. The\n * host bind() does not interpolate, so we always run the result through\n * here for any key the caller asked to format. Numeric / object placeholders\n * are coerced to strings; missing placeholders are left intact so a\n * missing key is visible in the rendered output. */\nexport function interpolate(\n template: string,\n vars?: Readonly<Record<string, unknown>>,\n): string {\n if (!vars) return template\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) => {\n const value = vars[name]\n if (value === undefined) return match\n return String(value)\n })\n}\n\n/** Detect the active language from the locale snapshot or browser hints. */\nfunction detectLocale(ctx: AnyCtx): SupportedLocale {\n try {\n const active = ctx.locale?.getSnapshot?.().active\n if (active === 'zh' || active?.toLowerCase().startsWith('zh-')) return 'zh'\n if (active === 'en' || active?.toLowerCase().startsWith('en-')) return 'en'\n } catch {\n // Fall through to browser hints when the locale face is unavailable.\n }\n\n const htmlLanguage = typeof document === 'undefined' ? '' : document.documentElement.lang\n if (htmlLanguage.toLowerCase().startsWith('zh')) return 'zh'\n const browserLanguages = typeof navigator === 'undefined' ? [] : navigator.languages\n if (browserLanguages.some((language) => language.toLowerCase().startsWith('zh'))) return 'zh'\n return 'en'\n}\n\n/**\n * Invoke the translation function supplied to a locale-aware slot. Keeping\n * this adapter distinct from `t(ctx, ...)` prevents a translator function\n * from being mistaken for a Cordis Context, which previously forced every\n * settings-page lookup through the English no-host fallback.\n */\nexport function translateWith(\n translator: unknown,\n key: string,\n vars?: Readonly<Record<string, unknown>>,\n): string {\n if (typeof translator !== 'function') return key\n return (translator as Translate)(key, vars)\n}\n\n/** Translation function. Callers always go through this — never the\n * underlying locale face — so the substitution / fallback path stays in\n * one place. `ctx` may be omitted (offline / SSR / tests) and we resolve\n * to en automatically. */\nexport function t(\n ctx: Context | undefined,\n key: string,\n vars?: Readonly<Record<string, unknown>>,\n): string {\n const anyCtx = ctx as AnyCtx | undefined\n let template: string | undefined\n // Prefer the host locale when it can answer; fall back to our table only\n // when the host does not know the key (e.g. unsupported language) or\n // there is no host at all. The bind contract is `string`, so a missing\n // key is signalled by throwing — catch and fall through.\n if (anyCtx?.locale) {\n try {\n template = anyCtx.locale.bind(DEEPPILOT_LOCALE_NS)(key)\n } catch {\n template = undefined\n }\n }\n if (template === undefined || template === key) {\n const locale = detectLocale(anyCtx ?? ({ locale: undefined } as unknown as AnyCtx))\n // Walk the local tables; the test for a missing key in our own zh/en\n // tables is a *bug* in this module and must not crash the page. We\n // surface the key itself so the gap is visible in the rendered\n // output rather than masked by a blank or an exception.\n template = TABLES[locale][key] ?? TABLES.zh[key] ?? TABLES.en[key] ?? key\n }\n return interpolate(template, vars)\n}\n\n/** Register both dictionaries and return the host-owned disposer. */\nexport function registerLocale(ctx: Context): () => void {\n const anyCtx = ctx as AnyCtx\n if (anyCtx.locale === undefined) return () => {}\n return anyCtx.locale.register(DEEPPILOT_LOCALE_NS, {\n zh: TABLES.zh,\n en: TABLES.en,\n })\n}\n\n/** Test-time access: read every key we ship. Used by the parity test to\n * guarantee zh and en stay in lock-step. */\nexport function _allKeysForTest(): ReadonlyArray<string> {\n return ALL_KEYS\n}\n","const CSS = String.raw`\n.pbb-section{--pbb-ink:var(--dsw-alias-label-primary,#0f1115);--pbb-secondary:var(--dsw-alias-label-secondary,#61666b);--pbb-line:var(--dsw-alias-settings-card-stroke,var(--dsw-alias-border-l3,#e4e5e7));--pbb-fill:var(--dsw-alias-settings-card-fill,var(--dsw-alias-bg-layer-2,#fff));--pbb-soft:var(--dsw-alias-bg-module-platform,#f5f6f8);container:pbb/inline-size;max-width:760px;color:var(--pbb-ink);font-size:14px;line-height:20px;display:flex;flex-direction:column;gap:20px}\n.pbb-section *{box-sizing:border-box}\n.pbb-section :is(.pbb-action,.pbb-refresh,.pbb-iconButton,.pbb-cardHead,.pbb-menuAction,.pbb-targetButton),.pbb-section input{font-family:inherit}\n.pbb-icon{display:block;flex:none;color:inherit}\n.pbb-pageHeader{display:flex;align-items:flex-start;gap:12px;min-height:56px}\n.pbb-pageHeader>div{min-width:0;flex:1;padding-top:2px}\n.pbb-title{margin:0;font-size:20px;line-height:27px;font-weight:600;letter-spacing:-.3px}\n.pbb-intro{color:var(--pbb-secondary);font-size:14px;line-height:20px;margin:5px 0 0}\n.pbb-refresh{display:inline-flex;align-items:center;justify-content:center;gap:5px;height:28px;padding:0 7px;flex:none;border:0;border-radius:6px;background:transparent;color:var(--pbb-secondary);font-size:12px;cursor:pointer}\n.pbb-card{border:1px solid var(--pbb-line);border-radius:18px;background:var(--pbb-fill)}\n.pbb-cardTitle{margin:0;font-size:14px;line-height:20px;font-weight:600;color:var(--pbb-ink)}\n.pbb-cardBody{display:flex;flex-direction:column;gap:12px;padding:4px 16px 16px}\n.pbb-connections>.pbb-cardBody{padding:0;gap:0}\n.pbb-row{display:flex;align-items:center;gap:8px;min-width:0}\n.pbb-masterRow{display:flex;align-items:center;gap:12px;min-height:66px;padding:11px 16px}\n.pbb-controlText{display:flex;flex:1;min-width:0;flex-direction:column;gap:2px}\n.pbb-masterRow>.pbb-controlText{gap:4px}\n.pbb-controlTitle{font-size:14px;line-height:20px;font-weight:400;color:var(--pbb-ink)}\n.pbb-masterRow .pbb-controlTitle{font-weight:600}\n.pbb-controlDescription,.pbb-diag,.pbb-label,.pbb-value{font-size:12px;line-height:18px;color:var(--pbb-secondary)}\n.pbb-serviceSummary,.pbb-channelState{display:flex;align-items:center;flex-wrap:wrap;gap:6px;font-size:12px;line-height:18px;color:var(--pbb-secondary)}\n.pbb-serviceSummary{gap:5px}\n.pbb-serviceState{display:inline-flex}\n.pbb-metaDivider{height:10px;border-left:1px solid var(--pbb-line);margin:0 2px}\n.pbb-channel{position:relative}\n.pbb-channel::before{content:\"\";position:absolute;top:0;left:16px;right:16px;border-top:1px solid var(--pbb-line)}\n.pbb-channel+.pbb-channel::before{left:46px}\n.pbb-channelRow{gap:12px;min-height:60px;padding:8px 16px}\n.pbb-channelRow>.pbb-icon{color:var(--pbb-secondary)}\n.pbb-channelBody{display:flex;flex-direction:column;gap:12px;padding:2px 16px 14px 46px}\n.pbb-channel>.pbb-diag,.pbb-channel>.pbb-rowAction{margin:0;padding:0 16px 8px 46px}\n.pbb-fold[hidden]{display:none}\n.pbb-action:disabled,.pbb-refresh:disabled,.pbb-menuAction:disabled,.pbb-targetButton:disabled{opacity:.5;cursor:default}\n.pbb-action{display:inline-flex;align-items:center;justify-content:center;gap:5px;flex:none;height:28px;max-width:100%;padding:0 9px;border:1px solid var(--pbb-line);border-radius:6px;background:transparent;color:var(--pbb-secondary);font:inherit;font-size:14px;line-height:20px;text-decoration:none;cursor:pointer;white-space:nowrap}\n.pbb-addAction{display:flex;margin-left:auto}\n.pbb-buttonPrimary{background:var(--dsw-alias-button-primary-fill,var(--pbb-ink));border-color:transparent;color:var(--dsw-alias-label-primary-foreground,#fff)}\n.pbb-actionDangerGhost{color:var(--dsw-alias-state-error-primary,#bc2222);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary,#bc2222) 35%,transparent)}\n.pbb-iconButton{display:flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;padding:0;border:0;border-radius:6px;background:transparent;color:var(--pbb-secondary);cursor:pointer}\n.pbb-chev{display:inline-flex;flex:none;color:var(--pbb-secondary)}\n.pbb-chevIcon{width:14px;height:14px;display:block}\n[aria-expanded=\"true\"]>.pbb-chev,.pbb-helpDisclosure[open]>summary>.pbb-chev,.pbb-disclosure[open]>summary>.pbb-chev{transform:rotate(90deg)}\n.pbb-diag{margin:0;overflow-wrap:anywhere}\n.pbb-diagBad,.pbb-bad{color:var(--dsw-alias-state-error-primary,#bc2222)}\n.pbb-ok{color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#287a45) 65%,var(--pbb-ink))}\n.pbb-label{flex:1;min-width:0;font-weight:500;color:var(--pbb-ink)}\n.pbb-value{text-align:right;overflow-wrap:anywhere}\n.pbb-token{max-width:100%;font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--pbb-secondary);overflow-wrap:anywhere}\n.pbb-empty{margin:0;padding:16px;font-size:14px;line-height:20px;color:var(--pbb-secondary)}\n.pbb-limitRow{display:flex;align-items:center;gap:12px}\n.pbb-limitControl{display:flex;align-items:center;gap:8px;flex:none}\n.pbb-numberInput,.pbb-deviceNameInput{min-width:0;height:28px;border:1px solid var(--pbb-line);border-radius:6px;background:var(--dsw-alias-bg-layer-3,var(--pbb-fill));color:var(--pbb-ink);font:inherit;font-size:14px;line-height:20px;padding:3px 8px;caret-color:var(--pbb-ink)}\n.pbb-numberInput{width:72px}\n.pbb-numberInput:disabled,.pbb-deviceNameInput:disabled{opacity:.5}\n.pbb-endpoint{user-select:all}\n.pbb-devicesSection{display:flex;flex-direction:column;gap:8px}\n.pbb-devicesHeader{display:flex;align-items:center;gap:8px;min-height:44px;padding:0 2px}\n.pbb-deviceCount{font-size:12px;line-height:18px;color:var(--pbb-secondary);white-space:nowrap}\n.pbb-devicesCard{overflow:visible}\n.pbb-deviceList{display:flex;flex-direction:column}\n.pbb-deviceRow{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:12px;row-gap:0;min-height:56px;padding:6px 14px 6px 16px}\n.pbb-deviceRow+.pbb-deviceRow::before{content:\"\";position:absolute;top:0;left:46px;right:16px;border-top:1px solid var(--pbb-line)}\n.pbb-deviceRow:has(details[open]){z-index:2}\n.pbb-deviceMain{display:flex;align-items:center;gap:12px;min-width:0}\n.pbb-deviceMain>.pbb-icon{color:var(--pbb-secondary)}\n.pbb-deviceText{display:flex;flex-direction:column;gap:2px;min-width:0}\n.pbb-deviceName{font-size:14px;line-height:20px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.pbb-deviceMeta{display:flex;flex-wrap:wrap;gap:0 6px;color:var(--pbb-secondary);font-size:12px;line-height:18px}\n.pbb-deviceMeta>*+*::before{content:\"\\00B7\";margin-right:6px}\n.pbb-deviceActions{grid-row:1;grid-column:2;display:flex;align-items:center}\n.pbb-deviceRenameForm,.pbb-deviceConfirm{grid-column:1/-1;display:flex;gap:8px;padding:8px 0;min-width:0}\n.pbb-deviceRenameForm{flex-wrap:wrap}\n.pbb-deviceNameInput{flex:1}\n.pbb-deviceRenameActions{display:flex;align-items:center;gap:5px;flex:none}\n.pbb-deviceConfirm{flex-direction:column}\n.pbb-deviceMessage{padding:10px 16px}\n.pbb-deviceMenu{position:relative}\n.pbb-deviceMenu>summary{list-style:none}\n.pbb-deviceMenu>summary::-webkit-details-marker{display:none}\n.pbb-deviceMenuBody{position:absolute;z-index:3;top:34px;right:0;width:250px;max-width:calc(100cqw - 32px);padding:5px;border:1px solid var(--pbb-line);border-radius:10px;background:var(--dsw-alias-bg-layer-3,var(--pbb-fill));box-shadow:0 8px 24px color-mix(in srgb,var(--pbb-ink) 12%,transparent)}\n.pbb-deviceMenuInfo{display:flex;flex-direction:column;gap:3px;padding:7px 8px 10px;border-bottom:1px solid var(--pbb-line)}\n.pbb-menuAction{display:block;width:100%;min-height:32px;padding:5px 8px;border:0;border-radius:5px;background:transparent;color:var(--pbb-ink);text-align:left;font:inherit;font-size:14px;cursor:pointer}\n.pbb-menuDanger{color:var(--dsw-alias-state-error-primary,#bc2222)}\n.pbb-actionBusy{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--pbb-secondary)}\n.pbb-actionBusy::before{content:\"\";width:10px;height:10px;border:1.5px solid var(--pbb-line);border-top-color:currentColor;border-radius:50%;animation:pbb-spin .7s linear infinite}\n@keyframes pbb-spin{to{transform:rotate(360deg)}}\n.pbb-rowAction{display:flex;flex-wrap:wrap;gap:8px}\n.pbb-pairingPanel{border:1px solid var(--pbb-line);border-radius:16px;padding:16px;background:var(--pbb-fill)}\n.pbb-pairingHeader{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}\n.pbb-pairingBody{display:flex;flex-direction:column;gap:10px}\n.pbb-targetList{display:flex;flex-wrap:wrap;gap:4px;min-width:0}\n.pbb-targetButton{max-width:100%;padding:5px 9px;border:1px solid transparent;border-radius:7px;background:var(--pbb-soft);color:var(--pbb-secondary);font:inherit;font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}\n.pbb-targetSelected{color:var(--pbb-ink);border-color:var(--pbb-line);background:var(--pbb-fill)}\n.pbb-qrPanel{display:grid;grid-template-columns:224px minmax(0,1fr);gap:20px;align-items:start}\n.pbb-qrImage{display:block;width:224px;height:224px;max-width:100%;padding:8px;border-radius:12px;background:#fff}\n.pbb-countdown{margin-top:10px;display:flex;flex-direction:column;gap:6px}\n.pbb-countdownBar{height:4px;border-radius:99px;background:var(--pbb-soft);overflow:hidden}\n.pbb-countdownBar i{display:block;width:100%;height:100%;transform-origin:left center;background:var(--dsw-alias-state-business-primary,#4176e6);border-radius:99px}\n.pbb-countdownText{font-size:12px;line-height:18px;color:var(--pbb-secondary);font-variant-numeric:tabular-nums}\n.pbb-pairInfo,.pbb-pairCodeBlock{display:flex;flex-direction:column;gap:8px;min-width:0}\n.pbb-pairCodeLabel,.pbb-qrHint{font-size:12px;line-height:18px;color:var(--pbb-secondary);margin:0}\n.pbb-pairCodeRow{display:flex;flex-wrap:wrap;align-items:center;gap:8px}\n.pbb-pairCode{font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;overflow-wrap:anywhere;user-select:all}\n.pbb-tools{border-radius:16px;overflow:hidden}\n.pbb-toolSection+.pbb-toolSection{border-top:1px solid var(--pbb-line)}\n.pbb-cardHead{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;padding:0 16px;border:0;background:transparent;color:var(--pbb-secondary);font:inherit;text-align:left;cursor:pointer}\n.pbb-cardHead>.pbb-cardTitle{flex:1;font-weight:400}\n.pbb-toolMeta{max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;color:var(--pbb-secondary)}\n.pbb-toolMeta.pbb-ok{color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#287a45) 65%,var(--pbb-ink))}\n.pbb-toolMeta.pbb-bad{color:var(--dsw-alias-state-error-primary,#bc2222)}\n.pbb-testGrid{display:flex;flex-direction:column;gap:0}\n.pbb-testItem{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--pbb-line)}\n.pbb-testTitle{font-size:14px;line-height:20px;font-weight:500;color:var(--pbb-ink)}\n.pbb-testDescription{font-size:12px;line-height:18px;color:var(--pbb-secondary)}\n.pbb-helpBody,.pbb-disclosureBody{display:flex;flex-direction:column;gap:14px}\n.pbb-helpSection{display:flex;flex-direction:column;gap:6px}\n.pbb-helpHeading{font-size:14px;line-height:20px;font-weight:500;color:var(--pbb-ink)}\n.pbb-helpList{margin:0;padding-left:20px;font-size:14px;line-height:22px;color:var(--pbb-secondary)}\n.pbb-helpList li+li{margin-top:4px}\n.pbb-helpText{margin:0;font-size:14px;line-height:22px;color:var(--pbb-secondary)}\n.pbb-helpCode{display:block;margin:0;padding:10px;border:1px solid var(--pbb-line);border-radius:8px;background:var(--pbb-soft);color:var(--pbb-ink);font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap;overflow-wrap:anywhere}\n.pbb-helpLink{color:var(--pbb-ink);text-decoration:underline;text-underline-offset:3px}\n.pbb-helpDisclosure>summary{display:flex;align-items:center;gap:6px;min-height:28px;list-style:none;cursor:pointer;color:var(--pbb-secondary);font-size:12px}\n.pbb-helpDisclosure>summary::-webkit-details-marker{display:none}\n.pbb-helpDisclosure[open]>.pbb-helpBody{padding-top:10px}\n.pbb-runtimeList{display:flex;flex-direction:column}\n.pbb-runtimeRow{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--pbb-line)}\n.pbb-runtimeRow>.pbb-row{flex:1;min-width:0}\n.pbb-updateRow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;color:var(--pbb-ink);font-size:14px;text-decoration:none}\n.pbb-resultRow{display:flex;align-items:flex-start;gap:6px}\n.pbb-resultIcon{display:inline-flex;flex:none;margin-top:3px;color:var(--dsw-alias-state-success-primary,#287a45)}\n.pbb-resultIconBad{color:var(--dsw-alias-state-error-primary,#bc2222)}\n.pbb-disclosure>summary{list-style:none;display:flex;align-items:center;gap:10px;min-height:44px;padding:0 16px;cursor:pointer;font-size:14px}\n.pbb-disclosure>summary::-webkit-details-marker{display:none}\n.pbb-disclosureBody{padding:2px 16px 16px}\n.pbb-disclosureTitle{flex:1}\n.pbb-section :is(.pbb-action,.pbb-refresh,.pbb-iconButton,.pbb-cardHead,.pbb-menuAction,.pbb-targetButton,input,summary,a):focus-visible{outline:2px solid var(--dsw-focus-ring-color,#5276b4);outline-offset:2px}\n@media (hover:hover) and (pointer:fine){.pbb-refresh:hover:not(:disabled),.pbb-iconButton:hover,.pbb-action:hover:not(:disabled),.pbb-cardHead:hover,.pbb-menuAction:hover:not(:disabled){background:var(--pbb-soft)}.pbb-buttonPrimary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,#30343b)}.pbb-action:active:not(:disabled),.pbb-refresh:active:not(:disabled),.pbb-iconButton:active{transform:scale(.97)}}\n@media (prefers-reduced-motion:reduce){.pbb-action,.pbb-refresh,.pbb-iconButton{transition:none;transform:none!important}.pbb-actionBusy::before{animation:none}}\n@container pbb (max-width:480px){.pbb-qrPanel{grid-template-columns:1fr}.pbb-limitRow{align-items:flex-start;flex-direction:column}.pbb-limitControl{align-self:flex-end}.pbb-deviceMeta{column-gap:4px}.pbb-toolMeta{max-width:42%}.pbb-channelRow{gap:8px}.pbb-testItem{flex-wrap:wrap}.pbb-testItem>.pbb-controlText{flex-basis:65%}}\n@container pbb (max-width:340px){.pbb-devicesHeader{flex-wrap:wrap}.pbb-deviceRow{column-gap:6px;padding-right:10px}.pbb-channelBody{padding-left:16px}.pbb-toolMeta{max-width:38%}}\n@media (pointer:coarse){.pbb-action,.pbb-iconButton,.pbb-refresh,.pbb-targetButton,.pbb-menuAction,.pbb-helpDisclosure>summary{min-width:44px;min-height:44px}.pbb-numberInput,.pbb-deviceNameInput{height:44px;font-size:16px}.pbb-deviceMenuBody{top:48px}}\n`\n\n/**\n * Client bundle id, identical to the `window.__ModuleLoader__.load({ id })`\n * identity emitted by tsdown.config.ts. DSH's module system owns style\n * teardown by package id, so this tag must carry the same value.\n */\nconst PLUGIN_ID = 'dsh-deeppilot'\n\n/**\n * Claim this plugin's page stylesheet against DSH's style ownership.\n *\n * `ClientModuleSystem` tags untagged `<style>` elements only during factory\n * materialization; this sheet is injected from `apply()`, which runs after\n * that point, so it would never be attributed to us. Stamping `data-plugin`\n * ourselves lets the module system's `removeOwnedStyles(id)` delete the sheet\n * when the plugin is unloaded at runtime — the rc.2 Plugin Manager and client\n * entry reconciler both support live removal, and an\n * orphaned sheet would otherwise keep styling a page we no longer own.\n */\nexport function injectCss(): void {\n if (typeof document === 'undefined') return\n const id = 'dsh-deeppilot/page.css'\n if (document.querySelector('style[data-plugin-css=\"' + id + '\"]') !== null) return\n const tag = document.createElement('style')\n tag.setAttribute('data-plugin', PLUGIN_ID)\n tag.setAttribute('data-plugin-css', id)\n tag.textContent = CSS\n document.head.appendChild(tag)\n}\n","import { createElement as h } from 'react'\n\ntype IconName = 'phone' | 'wifi' | 'globe' | 'refresh' | 'plus' | 'more' | 'activity' | 'info' | 'ready' | 'attention'\n\n/** 设置页的小图标共用线宽与 currentColor,随宿主主题变色,不额外引入图标包。 */\nexport function settingsIcon(name: IconName, size = 18): any {\n const path = (d: string): any => h('path', { d })\n const circle = (cx: number, cy: number, r: number): any => h('circle', { cx, cy, r })\n const shapes: Record<IconName, () => any[]> = {\n phone: () => [h('rect', { x: 6.5, y: 2.5, width: 11, height: 19, rx: 2.2 }), path('M10 5h4M11 18.5h2')],\n wifi: () => [path('M2 8.8a16 16 0 0 1 20 0M5 12.1a11 11 0 0 1 14 0M8.3 15.5a6 6 0 0 1 7.4 0'), circle(12, 19, .7)],\n globe: () => [circle(12, 12, 9), path('M3 12h18M12 3a17 17 0 0 1 0 18 17 17 0 0 1 0-18')],\n refresh: () => [path('M20 7v5h-5M4 17v-5h5M6.1 7a7 7 0 0 1 11.5-1L20 9M4 15l2.4 3A7 7 0 0 0 18 17')],\n plus: () => [path('M12 5v14M5 12h14')],\n more: () => [circle(5, 12, 1.2), circle(12, 12, 1.2), circle(19, 12, 1.2)],\n activity: () => [path('M3 12h4l3-7 4 14 3-7h4')],\n info: () => [circle(12, 12, 9), path('M12 11v6M12 7h.01')],\n ready: () => [circle(12, 12, 9), path('m8 12 3 3 5-6')],\n attention: () => [circle(12, 12, 9), path('M12 7v6M12 17h.01')],\n }\n return h('svg', {\n className: 'pbb-icon', viewBox: '0 0 24 24', width: size, height: size,\n fill: 'none', stroke: 'currentColor', strokeWidth: 1.6,\n strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true,\n }, ...shapes[name]())\n}\n","import { createElement as h, useEffect, useRef } from 'react'\nimport type { Translate } from './i18n.ts'\nimport { settingsIcon } from './settings-icons.ts'\n\ninterface DeviceActionsProps {\n name: string\n fingerprint: string\n customName?: string\n canRename: boolean\n canRevoke: boolean\n onRename: () => void\n onRevoke: () => void\n t: Translate\n}\n\n/**\n * 原生 disclosure(折叠控件)负责 Enter/Space 与焦点顺序;操作仍是普通按钮,\n * 不冒充需要方向键导航的 ARIA menu。详情只在展开时进入无障碍读取顺序。\n */\nexport function DeviceActions(props: DeviceActionsProps): any {\n const ref = useRef<HTMLDetailsElement>(null)\n const close = (restoreFocus = false): void => {\n const details = ref.current\n if (details === null) return\n details.open = false\n if (restoreFocus) details.querySelector('summary')?.focus()\n }\n useEffect(() => {\n const outside = (event: PointerEvent): void => {\n if (event.target instanceof Node && !ref.current?.contains(event.target)) close()\n }\n document.addEventListener('pointerdown', outside)\n return () => document.removeEventListener('pointerdown', outside)\n }, [])\n const act = (action: () => void): void => { close(); action() }\n return h('details', {\n ref, className: 'pbb-deviceMenu',\n onKeyDown: (event: { key: string; preventDefault: () => void; stopPropagation: () => void }) => {\n if (event.key !== 'Escape' || !ref.current?.open) return\n event.preventDefault()\n event.stopPropagation()\n close(true)\n },\n },\n h('summary', {\n className: 'pbb-iconButton',\n 'aria-label': props.t('devices.moreAria', { name: props.name }),\n }, settingsIcon('more', 16)),\n h('div', { className: 'pbb-deviceMenuBody', 'aria-label': props.t('devices.col.actions') },\n h('div', { className: 'pbb-deviceMenuInfo' },\n props.customName ? h('span', { className: 'pbb-diag' }, props.t('devices.customBadge')) : null,\n h('span', { className: 'pbb-diag' }, props.t('devices.col.fingerprint')),\n h('code', { className: 'pbb-token' }, props.fingerprint || '—')),\n h('button', {\n type: 'button', className: 'pbb-menuAction', disabled: !props.canRename,\n 'aria-label': props.t('devices.renameAria', { name: props.name }),\n onClick: () => act(props.onRename),\n }, props.t('devices.rename')),\n h('button', {\n type: 'button', className: 'pbb-menuAction pbb-menuDanger', disabled: !props.canRevoke,\n 'aria-label': props.t('devices.revokeAria', { name: props.name }),\n onClick: () => act(props.onRevoke),\n }, props.t('devices.revoke'))))\n}\n","// can-promise has a crash in some versions of react native that dont have\n// standard global objects\n// https://github.com/soldair/node-qrcode/issues/157\n\nmodule.exports = function () {\n return typeof Promise === 'function' && Promise.prototype && Promise.prototype.then\n}\n","let toSJISFunction\nconst CODEWORDS_COUNT = [\n 0, // Not used\n 26, 44, 70, 100, 134, 172, 196, 242, 292, 346,\n 404, 466, 532, 581, 655, 733, 815, 901, 991, 1085,\n 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 2185,\n 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706\n]\n\n/**\n * Returns the QR Code size for the specified version\n *\n * @param {Number} version QR Code version\n * @return {Number} size of QR code\n */\nexports.getSymbolSize = function getSymbolSize (version) {\n if (!version) throw new Error('\"version\" cannot be null or undefined')\n if (version < 1 || version > 40) throw new Error('\"version\" should be in range from 1 to 40')\n return version * 4 + 17\n}\n\n/**\n * Returns the total number of codewords used to store data and EC information.\n *\n * @param {Number} version QR Code version\n * @return {Number} Data length in bits\n */\nexports.getSymbolTotalCodewords = function getSymbolTotalCodewords (version) {\n return CODEWORDS_COUNT[version]\n}\n\n/**\n * Encode data with Bose-Chaudhuri-Hocquenghem\n *\n * @param {Number} data Value to encode\n * @return {Number} Encoded value\n */\nexports.getBCHDigit = function (data) {\n let digit = 0\n\n while (data !== 0) {\n digit++\n data >>>= 1\n }\n\n return digit\n}\n\nexports.setToSJISFunction = function setToSJISFunction (f) {\n if (typeof f !== 'function') {\n throw new Error('\"toSJISFunc\" is not a valid function.')\n }\n\n toSJISFunction = f\n}\n\nexports.isKanjiModeEnabled = function () {\n return typeof toSJISFunction !== 'undefined'\n}\n\nexports.toSJIS = function toSJIS (kanji) {\n return toSJISFunction(kanji)\n}\n","exports.L = { bit: 1 }\nexports.M = { bit: 0 }\nexports.Q = { bit: 3 }\nexports.H = { bit: 2 }\n\nfunction fromString (string) {\n if (typeof string !== 'string') {\n throw new Error('Param is not a string')\n }\n\n const lcStr = string.toLowerCase()\n\n switch (lcStr) {\n case 'l':\n case 'low':\n return exports.L\n\n case 'm':\n case 'medium':\n return exports.M\n\n case 'q':\n case 'quartile':\n return exports.Q\n\n case 'h':\n case 'high':\n return exports.H\n\n default:\n throw new Error('Unknown EC Level: ' + string)\n }\n}\n\nexports.isValid = function isValid (level) {\n return level && typeof level.bit !== 'undefined' &&\n level.bit >= 0 && level.bit < 4\n}\n\nexports.from = function from (value, defaultValue) {\n if (exports.isValid(value)) {\n return value\n }\n\n try {\n return fromString(value)\n } catch (e) {\n return defaultValue\n }\n}\n","function BitBuffer () {\n this.buffer = []\n this.length = 0\n}\n\nBitBuffer.prototype = {\n\n get: function (index) {\n const bufIndex = Math.floor(index / 8)\n return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) === 1\n },\n\n put: function (num, length) {\n for (let i = 0; i < length; i++) {\n this.putBit(((num >>> (length - i - 1)) & 1) === 1)\n }\n },\n\n getLengthInBits: function () {\n return this.length\n },\n\n putBit: function (bit) {\n const bufIndex = Math.floor(this.length / 8)\n if (this.buffer.length <= bufIndex) {\n this.buffer.push(0)\n }\n\n if (bit) {\n this.buffer[bufIndex] |= (0x80 >>> (this.length % 8))\n }\n\n this.length++\n }\n}\n\nmodule.exports = BitBuffer\n","/**\n * Helper class to handle QR Code symbol modules\n *\n * @param {Number} size Symbol size\n */\nfunction BitMatrix (size) {\n if (!size || size < 1) {\n throw new Error('BitMatrix size must be defined and greater than 0')\n }\n\n this.size = size\n this.data = new Uint8Array(size * size)\n this.reservedBit = new Uint8Array(size * size)\n}\n\n/**\n * Set bit value at specified location\n * If reserved flag is set, this bit will be ignored during masking process\n *\n * @param {Number} row\n * @param {Number} col\n * @param {Boolean} value\n * @param {Boolean} reserved\n */\nBitMatrix.prototype.set = function (row, col, value, reserved) {\n const index = row * this.size + col\n this.data[index] = value\n if (reserved) this.reservedBit[index] = true\n}\n\n/**\n * Returns bit value at specified location\n *\n * @param {Number} row\n * @param {Number} col\n * @return {Boolean}\n */\nBitMatrix.prototype.get = function (row, col) {\n return this.data[row * this.size + col]\n}\n\n/**\n * Applies xor operator at specified location\n * (used during masking process)\n *\n * @param {Number} row\n * @param {Number} col\n * @param {Boolean} value\n */\nBitMatrix.prototype.xor = function (row, col, value) {\n this.data[row * this.size + col] ^= value\n}\n\n/**\n * Check if bit at specified location is reserved\n *\n * @param {Number} row\n * @param {Number} col\n * @return {Boolean}\n */\nBitMatrix.prototype.isReserved = function (row, col) {\n return this.reservedBit[row * this.size + col]\n}\n\nmodule.exports = BitMatrix\n","/**\n * Alignment pattern are fixed reference pattern in defined positions\n * in a matrix symbology, which enables the decode software to re-synchronise\n * the coordinate mapping of the image modules in the event of moderate amounts\n * of distortion of the image.\n *\n * Alignment patterns are present only in QR Code symbols of version 2 or larger\n * and their number depends on the symbol version.\n */\n\nconst getSymbolSize = require('./utils').getSymbolSize\n\n/**\n * Calculate the row/column coordinates of the center module of each alignment pattern\n * for the specified QR Code version.\n *\n * The alignment patterns are positioned symmetrically on either side of the diagonal\n * running from the top left corner of the symbol to the bottom right corner.\n *\n * Since positions are simmetrical only half of the coordinates are returned.\n * Each item of the array will represent in turn the x and y coordinate.\n * @see {@link getPositions}\n *\n * @param {Number} version QR Code version\n * @return {Array} Array of coordinate\n */\nexports.getRowColCoords = function getRowColCoords (version) {\n if (version === 1) return []\n\n const posCount = Math.floor(version / 7) + 2\n const size = getSymbolSize(version)\n const intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2\n const positions = [size - 7] // Last coord is always (size - 7)\n\n for (let i = 1; i < posCount - 1; i++) {\n positions[i] = positions[i - 1] - intervals\n }\n\n positions.push(6) // First coord is always 6\n\n return positions.reverse()\n}\n\n/**\n * Returns an array containing the positions of each alignment pattern.\n * Each array's element represent the center point of the pattern as (x, y) coordinates\n *\n * Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords}\n * and filtering out the items that overlaps with finder pattern\n *\n * @example\n * For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38.\n * The alignment patterns, therefore, are to be centered on (row, column)\n * positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38).\n * Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns\n * and are not therefore used for alignment patterns.\n *\n * let pos = getPositions(7)\n * // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]]\n *\n * @param {Number} version QR Code version\n * @return {Array} Array of coordinates\n */\nexports.getPositions = function getPositions (version) {\n const coords = []\n const pos = exports.getRowColCoords(version)\n const posLength = pos.length\n\n for (let i = 0; i < posLength; i++) {\n for (let j = 0; j < posLength; j++) {\n // Skip if position is occupied by finder patterns\n if ((i === 0 && j === 0) || // top-left\n (i === 0 && j === posLength - 1) || // bottom-left\n (i === posLength - 1 && j === 0)) { // top-right\n continue\n }\n\n coords.push([pos[i], pos[j]])\n }\n }\n\n return coords\n}\n","const getSymbolSize = require('./utils').getSymbolSize\nconst FINDER_PATTERN_SIZE = 7\n\n/**\n * Returns an array containing the positions of each finder pattern.\n * Each array's element represent the top-left point of the pattern as (x, y) coordinates\n *\n * @param {Number} version QR Code version\n * @return {Array} Array of coordinates\n */\nexports.getPositions = function getPositions (version) {\n const size = getSymbolSize(version)\n\n return [\n // top-left\n [0, 0],\n // top-right\n [size - FINDER_PATTERN_SIZE, 0],\n // bottom-left\n [0, size - FINDER_PATTERN_SIZE]\n ]\n}\n","/**\n * Data mask pattern reference\n * @type {Object}\n */\nexports.Patterns = {\n PATTERN000: 0,\n PATTERN001: 1,\n PATTERN010: 2,\n PATTERN011: 3,\n PATTERN100: 4,\n PATTERN101: 5,\n PATTERN110: 6,\n PATTERN111: 7\n}\n\n/**\n * Weighted penalty scores for the undesirable features\n * @type {Object}\n */\nconst PenaltyScores = {\n N1: 3,\n N2: 3,\n N3: 40,\n N4: 10\n}\n\n/**\n * Check if mask pattern value is valid\n *\n * @param {Number} mask Mask pattern\n * @return {Boolean} true if valid, false otherwise\n */\nexports.isValid = function isValid (mask) {\n return mask != null && mask !== '' && !isNaN(mask) && mask >= 0 && mask <= 7\n}\n\n/**\n * Returns mask pattern from a value.\n * If value is not valid, returns undefined\n *\n * @param {Number|String} value Mask pattern value\n * @return {Number} Valid mask pattern or undefined\n */\nexports.from = function from (value) {\n return exports.isValid(value) ? parseInt(value, 10) : undefined\n}\n\n/**\n* Find adjacent modules in row/column with the same color\n* and assign a penalty value.\n*\n* Points: N1 + i\n* i is the amount by which the number of adjacent modules of the same color exceeds 5\n*/\nexports.getPenaltyN1 = function getPenaltyN1 (data) {\n const size = data.size\n let points = 0\n let sameCountCol = 0\n let sameCountRow = 0\n let lastCol = null\n let lastRow = null\n\n for (let row = 0; row < size; row++) {\n sameCountCol = sameCountRow = 0\n lastCol = lastRow = null\n\n for (let col = 0; col < size; col++) {\n let module = data.get(row, col)\n if (module === lastCol) {\n sameCountCol++\n } else {\n if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5)\n lastCol = module\n sameCountCol = 1\n }\n\n module = data.get(col, row)\n if (module === lastRow) {\n sameCountRow++\n } else {\n if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5)\n lastRow = module\n sameCountRow = 1\n }\n }\n\n if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5)\n if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5)\n }\n\n return points\n}\n\n/**\n * Find 2x2 blocks with the same color and assign a penalty value\n *\n * Points: N2 * (m - 1) * (n - 1)\n */\nexports.getPenaltyN2 = function getPenaltyN2 (data) {\n const size = data.size\n let points = 0\n\n for (let row = 0; row < size - 1; row++) {\n for (let col = 0; col < size - 1; col++) {\n const last = data.get(row, col) +\n data.get(row, col + 1) +\n data.get(row + 1, col) +\n data.get(row + 1, col + 1)\n\n if (last === 4 || last === 0) points++\n }\n }\n\n return points * PenaltyScores.N2\n}\n\n/**\n * Find 1:1:3:1:1 ratio (dark:light:dark:light:dark) pattern in row/column,\n * preceded or followed by light area 4 modules wide\n *\n * Points: N3 * number of pattern found\n */\nexports.getPenaltyN3 = function getPenaltyN3 (data) {\n const size = data.size\n let points = 0\n let bitsCol = 0\n let bitsRow = 0\n\n for (let row = 0; row < size; row++) {\n bitsCol = bitsRow = 0\n for (let col = 0; col < size; col++) {\n bitsCol = ((bitsCol << 1) & 0x7FF) | data.get(row, col)\n if (col >= 10 && (bitsCol === 0x5D0 || bitsCol === 0x05D)) points++\n\n bitsRow = ((bitsRow << 1) & 0x7FF) | data.get(col, row)\n if (col >= 10 && (bitsRow === 0x5D0 || bitsRow === 0x05D)) points++\n }\n }\n\n return points * PenaltyScores.N3\n}\n\n/**\n * Calculate proportion of dark modules in entire symbol\n *\n * Points: N4 * k\n *\n * k is the rating of the deviation of the proportion of dark modules\n * in the symbol from 50% in steps of 5%\n */\nexports.getPenaltyN4 = function getPenaltyN4 (data) {\n let darkCount = 0\n const modulesCount = data.data.length\n\n for (let i = 0; i < modulesCount; i++) darkCount += data.data[i]\n\n const k = Math.abs(Math.ceil((darkCount * 100 / modulesCount) / 5) - 10)\n\n return k * PenaltyScores.N4\n}\n\n/**\n * Return mask value at given position\n *\n * @param {Number} maskPattern Pattern reference value\n * @param {Number} i Row\n * @param {Number} j Column\n * @return {Boolean} Mask value\n */\nfunction getMaskAt (maskPattern, i, j) {\n switch (maskPattern) {\n case exports.Patterns.PATTERN000: return (i + j) % 2 === 0\n case exports.Patterns.PATTERN001: return i % 2 === 0\n case exports.Patterns.PATTERN010: return j % 3 === 0\n case exports.Patterns.PATTERN011: return (i + j) % 3 === 0\n case exports.Patterns.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0\n case exports.Patterns.PATTERN101: return (i * j) % 2 + (i * j) % 3 === 0\n case exports.Patterns.PATTERN110: return ((i * j) % 2 + (i * j) % 3) % 2 === 0\n case exports.Patterns.PATTERN111: return ((i * j) % 3 + (i + j) % 2) % 2 === 0\n\n default: throw new Error('bad maskPattern:' + maskPattern)\n }\n}\n\n/**\n * Apply a mask pattern to a BitMatrix\n *\n * @param {Number} pattern Pattern reference number\n * @param {BitMatrix} data BitMatrix data\n */\nexports.applyMask = function applyMask (pattern, data) {\n const size = data.size\n\n for (let col = 0; col < size; col++) {\n for (let row = 0; row < size; row++) {\n if (data.isReserved(row, col)) continue\n data.xor(row, col, getMaskAt(pattern, row, col))\n }\n }\n}\n\n/**\n * Returns the best mask pattern for data\n *\n * @param {BitMatrix} data\n * @return {Number} Mask pattern reference number\n */\nexports.getBestMask = function getBestMask (data, setupFormatFunc) {\n const numPatterns = Object.keys(exports.Patterns).length\n let bestPattern = 0\n let lowerPenalty = Infinity\n\n for (let p = 0; p < numPatterns; p++) {\n setupFormatFunc(p)\n exports.applyMask(p, data)\n\n // Calculate penalty\n const penalty =\n exports.getPenaltyN1(data) +\n exports.getPenaltyN2(data) +\n exports.getPenaltyN3(data) +\n exports.getPenaltyN4(data)\n\n // Undo previously applied mask\n exports.applyMask(p, data)\n\n if (penalty < lowerPenalty) {\n lowerPenalty = penalty\n bestPattern = p\n }\n }\n\n return bestPattern\n}\n","const ECLevel = require('./error-correction-level')\r\n\r\nconst EC_BLOCKS_TABLE = [\r\n// L M Q H\r\n 1, 1, 1, 1,\r\n 1, 1, 1, 1,\r\n 1, 1, 2, 2,\r\n 1, 2, 2, 4,\r\n 1, 2, 4, 4,\r\n 2, 4, 4, 4,\r\n 2, 4, 6, 5,\r\n 2, 4, 6, 6,\r\n 2, 5, 8, 8,\r\n 4, 5, 8, 8,\r\n 4, 5, 8, 11,\r\n 4, 8, 10, 11,\r\n 4, 9, 12, 16,\r\n 4, 9, 16, 16,\r\n 6, 10, 12, 18,\r\n 6, 10, 17, 16,\r\n 6, 11, 16, 19,\r\n 6, 13, 18, 21,\r\n 7, 14, 21, 25,\r\n 8, 16, 20, 25,\r\n 8, 17, 23, 25,\r\n 9, 17, 23, 34,\r\n 9, 18, 25, 30,\r\n 10, 20, 27, 32,\r\n 12, 21, 29, 35,\r\n 12, 23, 34, 37,\r\n 12, 25, 34, 40,\r\n 13, 26, 35, 42,\r\n 14, 28, 38, 45,\r\n 15, 29, 40, 48,\r\n 16, 31, 43, 51,\r\n 17, 33, 45, 54,\r\n 18, 35, 48, 57,\r\n 19, 37, 51, 60,\r\n 19, 38, 53, 63,\r\n 20, 40, 56, 66,\r\n 21, 43, 59, 70,\r\n 22, 45, 62, 74,\r\n 24, 47, 65, 77,\r\n 25, 49, 68, 81\r\n]\r\n\r\nconst EC_CODEWORDS_TABLE = [\r\n// L M Q H\r\n 7, 10, 13, 17,\r\n 10, 16, 22, 28,\r\n 15, 26, 36, 44,\r\n 20, 36, 52, 64,\r\n 26, 48, 72, 88,\r\n 36, 64, 96, 112,\r\n 40, 72, 108, 130,\r\n 48, 88, 132, 156,\r\n 60, 110, 160, 192,\r\n 72, 130, 192, 224,\r\n 80, 150, 224, 264,\r\n 96, 176, 260, 308,\r\n 104, 198, 288, 352,\r\n 120, 216, 320, 384,\r\n 132, 240, 360, 432,\r\n 144, 280, 408, 480,\r\n 168, 308, 448, 532,\r\n 180, 338, 504, 588,\r\n 196, 364, 546, 650,\r\n 224, 416, 600, 700,\r\n 224, 442, 644, 750,\r\n 252, 476, 690, 816,\r\n 270, 504, 750, 900,\r\n 300, 560, 810, 960,\r\n 312, 588, 870, 1050,\r\n 336, 644, 952, 1110,\r\n 360, 700, 1020, 1200,\r\n 390, 728, 1050, 1260,\r\n 420, 784, 1140, 1350,\r\n 450, 812, 1200, 1440,\r\n 480, 868, 1290, 1530,\r\n 510, 924, 1350, 1620,\r\n 540, 980, 1440, 1710,\r\n 570, 1036, 1530, 1800,\r\n 570, 1064, 1590, 1890,\r\n 600, 1120, 1680, 1980,\r\n 630, 1204, 1770, 2100,\r\n 660, 1260, 1860, 2220,\r\n 720, 1316, 1950, 2310,\r\n 750, 1372, 2040, 2430\r\n]\r\n\r\n/**\r\n * Returns the number of error correction block that the QR Code should contain\r\n * for the specified version and error correction level.\r\n *\r\n * @param {Number} version QR Code version\r\n * @param {Number} errorCorrectionLevel Error correction level\r\n * @return {Number} Number of error correction blocks\r\n */\r\nexports.getBlocksCount = function getBlocksCount (version, errorCorrectionLevel) {\r\n switch (errorCorrectionLevel) {\r\n case ECLevel.L:\r\n return EC_BLOCKS_TABLE[(version - 1) * 4 + 0]\r\n case ECLevel.M:\r\n return EC_BLOCKS_TABLE[(version - 1) * 4 + 1]\r\n case ECLevel.Q:\r\n return EC_BLOCKS_TABLE[(version - 1) * 4 + 2]\r\n case ECLevel.H:\r\n return EC_BLOCKS_TABLE[(version - 1) * 4 + 3]\r\n default:\r\n return undefined\r\n }\r\n}\r\n\r\n/**\r\n * Returns the number of error correction codewords to use for the specified\r\n * version and error correction level.\r\n *\r\n * @param {Number} version QR Code version\r\n * @param {Number} errorCorrectionLevel Error correction level\r\n * @return {Number} Number of error correction codewords\r\n */\r\nexports.getTotalCodewordsCount = function getTotalCodewordsCount (version, errorCorrectionLevel) {\r\n switch (errorCorrectionLevel) {\r\n case ECLevel.L:\r\n return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0]\r\n case ECLevel.M:\r\n return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1]\r\n case ECLevel.Q:\r\n return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2]\r\n case ECLevel.H:\r\n return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3]\r\n default:\r\n return undefined\r\n }\r\n}\r\n","const EXP_TABLE = new Uint8Array(512)\nconst LOG_TABLE = new Uint8Array(256)\n/**\n * Precompute the log and anti-log tables for faster computation later\n *\n * For each possible value in the galois field 2^8, we will pre-compute\n * the logarithm and anti-logarithm (exponential) of this value\n *\n * ref {@link https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders#Introduction_to_mathematical_fields}\n */\n;(function initTables () {\n let x = 1\n for (let i = 0; i < 255; i++) {\n EXP_TABLE[i] = x\n LOG_TABLE[x] = i\n\n x <<= 1 // multiply by 2\n\n // The QR code specification says to use byte-wise modulo 100011101 arithmetic.\n // This means that when a number is 256 or larger, it should be XORed with 0x11D.\n if (x & 0x100) { // similar to x >= 256, but a lot faster (because 0x100 == 256)\n x ^= 0x11D\n }\n }\n\n // Optimization: double the size of the anti-log table so that we don't need to mod 255 to\n // stay inside the bounds (because we will mainly use this table for the multiplication of\n // two GF numbers, no more).\n // @see {@link mul}\n for (let i = 255; i < 512; i++) {\n EXP_TABLE[i] = EXP_TABLE[i - 255]\n }\n}())\n\n/**\n * Returns log value of n inside Galois Field\n *\n * @param {Number} n\n * @return {Number}\n */\nexports.log = function log (n) {\n if (n < 1) throw new Error('log(' + n + ')')\n return LOG_TABLE[n]\n}\n\n/**\n * Returns anti-log value of n inside Galois Field\n *\n * @param {Number} n\n * @return {Number}\n */\nexports.exp = function exp (n) {\n return EXP_TABLE[n]\n}\n\n/**\n * Multiplies two number inside Galois Field\n *\n * @param {Number} x\n * @param {Number} y\n * @return {Number}\n */\nexports.mul = function mul (x, y) {\n if (x === 0 || y === 0) return 0\n\n // should be EXP_TABLE[(LOG_TABLE[x] + LOG_TABLE[y]) % 255] if EXP_TABLE wasn't oversized\n // @see {@link initTables}\n return EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]]\n}\n","const GF = require('./galois-field')\n\n/**\n * Multiplies two polynomials inside Galois Field\n *\n * @param {Uint8Array} p1 Polynomial\n * @param {Uint8Array} p2 Polynomial\n * @return {Uint8Array} Product of p1 and p2\n */\nexports.mul = function mul (p1, p2) {\n const coeff = new Uint8Array(p1.length + p2.length - 1)\n\n for (let i = 0; i < p1.length; i++) {\n for (let j = 0; j < p2.length; j++) {\n coeff[i + j] ^= GF.mul(p1[i], p2[j])\n }\n }\n\n return coeff\n}\n\n/**\n * Calculate the remainder of polynomials division\n *\n * @param {Uint8Array} divident Polynomial\n * @param {Uint8Array} divisor Polynomial\n * @return {Uint8Array} Remainder\n */\nexports.mod = function mod (divident, divisor) {\n let result = new Uint8Array(divident)\n\n while ((result.length - divisor.length) >= 0) {\n const coeff = result[0]\n\n for (let i = 0; i < divisor.length; i++) {\n result[i] ^= GF.mul(divisor[i], coeff)\n }\n\n // remove all zeros from buffer head\n let offset = 0\n while (offset < result.length && result[offset] === 0) offset++\n result = result.slice(offset)\n }\n\n return result\n}\n\n/**\n * Generate an irreducible generator polynomial of specified degree\n * (used by Reed-Solomon encoder)\n *\n * @param {Number} degree Degree of the generator polynomial\n * @return {Uint8Array} Buffer containing polynomial coefficients\n */\nexports.generateECPolynomial = function generateECPolynomial (degree) {\n let poly = new Uint8Array([1])\n for (let i = 0; i < degree; i++) {\n poly = exports.mul(poly, new Uint8Array([1, GF.exp(i)]))\n }\n\n return poly\n}\n","const Polynomial = require('./polynomial')\n\nfunction ReedSolomonEncoder (degree) {\n this.genPoly = undefined\n this.degree = degree\n\n if (this.degree) this.initialize(this.degree)\n}\n\n/**\n * Initialize the encoder.\n * The input param should correspond to the number of error correction codewords.\n *\n * @param {Number} degree\n */\nReedSolomonEncoder.prototype.initialize = function initialize (degree) {\n // create an irreducible generator polynomial\n this.degree = degree\n this.genPoly = Polynomial.generateECPolynomial(this.degree)\n}\n\n/**\n * Encodes a chunk of data\n *\n * @param {Uint8Array} data Buffer containing input data\n * @return {Uint8Array} Buffer containing encoded data\n */\nReedSolomonEncoder.prototype.encode = function encode (data) {\n if (!this.genPoly) {\n throw new Error('Encoder not initialized')\n }\n\n // Calculate EC for this data block\n // extends data size to data+genPoly size\n const paddedData = new Uint8Array(data.length + this.degree)\n paddedData.set(data)\n\n // The error correction codewords are the remainder after dividing the data codewords\n // by a generator polynomial\n const remainder = Polynomial.mod(paddedData, this.genPoly)\n\n // return EC data blocks (last n byte, where n is the degree of genPoly)\n // If coefficients number in remainder are less than genPoly degree,\n // pad with 0s to the left to reach the needed number of coefficients\n const start = this.degree - remainder.length\n if (start > 0) {\n const buff = new Uint8Array(this.degree)\n buff.set(remainder, start)\n\n return buff\n }\n\n return remainder\n}\n\nmodule.exports = ReedSolomonEncoder\n","/**\n * Check if QR Code version is valid\n *\n * @param {Number} version QR Code version\n * @return {Boolean} true if valid version, false otherwise\n */\nexports.isValid = function isValid (version) {\n return !isNaN(version) && version >= 1 && version <= 40\n}\n","const numeric = '[0-9]+'\nconst alphanumeric = '[A-Z $%*+\\\\-./:]+'\nlet kanji = '(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|' +\n '[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|' +\n '[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|' +\n '[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+'\nkanji = kanji.replace(/u/g, '\\\\u')\n\nconst byte = '(?:(?![A-Z0-9 $%*+\\\\-./:]|' + kanji + ')(?:.|[\\r\\n]))+'\n\nexports.KANJI = new RegExp(kanji, 'g')\nexports.BYTE_KANJI = new RegExp('[^A-Z0-9 $%*+\\\\-./:]+', 'g')\nexports.BYTE = new RegExp(byte, 'g')\nexports.NUMERIC = new RegExp(numeric, 'g')\nexports.ALPHANUMERIC = new RegExp(alphanumeric, 'g')\n\nconst TEST_KANJI = new RegExp('^' + kanji + '$')\nconst TEST_NUMERIC = new RegExp('^' + numeric + '$')\nconst TEST_ALPHANUMERIC = new RegExp('^[A-Z0-9 $%*+\\\\-./:]+$')\n\nexports.testKanji = function testKanji (str) {\n return TEST_KANJI.test(str)\n}\n\nexports.testNumeric = function testNumeric (str) {\n return TEST_NUMERIC.test(str)\n}\n\nexports.testAlphanumeric = function testAlphanumeric (str) {\n return TEST_ALPHANUMERIC.test(str)\n}\n","const VersionCheck = require('./version-check')\nconst Regex = require('./regex')\n\n/**\n * Numeric mode encodes data from the decimal digit set (0 - 9)\n * (byte values 30HEX to 39HEX).\n * Normally, 3 data characters are represented by 10 bits.\n *\n * @type {Object}\n */\nexports.NUMERIC = {\n id: 'Numeric',\n bit: 1 << 0,\n ccBits: [10, 12, 14]\n}\n\n/**\n * Alphanumeric mode encodes data from a set of 45 characters,\n * i.e. 10 numeric digits (0 - 9),\n * 26 alphabetic characters (A - Z),\n * and 9 symbols (SP, $, %, *, +, -, ., /, :).\n * Normally, two input characters are represented by 11 bits.\n *\n * @type {Object}\n */\nexports.ALPHANUMERIC = {\n id: 'Alphanumeric',\n bit: 1 << 1,\n ccBits: [9, 11, 13]\n}\n\n/**\n * In byte mode, data is encoded at 8 bits per character.\n *\n * @type {Object}\n */\nexports.BYTE = {\n id: 'Byte',\n bit: 1 << 2,\n ccBits: [8, 16, 16]\n}\n\n/**\n * The Kanji mode efficiently encodes Kanji characters in accordance with\n * the Shift JIS system based on JIS X 0208.\n * The Shift JIS values are shifted from the JIS X 0208 values.\n * JIS X 0208 gives details of the shift coded representation.\n * Each two-byte character value is compacted to a 13-bit binary codeword.\n *\n * @type {Object}\n */\nexports.KANJI = {\n id: 'Kanji',\n bit: 1 << 3,\n ccBits: [8, 10, 12]\n}\n\n/**\n * Mixed mode will contain a sequences of data in a combination of any of\n * the modes described above\n *\n * @type {Object}\n */\nexports.MIXED = {\n bit: -1\n}\n\n/**\n * Returns the number of bits needed to store the data length\n * according to QR Code specifications.\n *\n * @param {Mode} mode Data mode\n * @param {Number} version QR Code version\n * @return {Number} Number of bits\n */\nexports.getCharCountIndicator = function getCharCountIndicator (mode, version) {\n if (!mode.ccBits) throw new Error('Invalid mode: ' + mode)\n\n if (!VersionCheck.isValid(version)) {\n throw new Error('Invalid version: ' + version)\n }\n\n if (version >= 1 && version < 10) return mode.ccBits[0]\n else if (version < 27) return mode.ccBits[1]\n return mode.ccBits[2]\n}\n\n/**\n * Returns the most efficient mode to store the specified data\n *\n * @param {String} dataStr Input data string\n * @return {Mode} Best mode\n */\nexports.getBestModeForData = function getBestModeForData (dataStr) {\n if (Regex.testNumeric(dataStr)) return exports.NUMERIC\n else if (Regex.testAlphanumeric(dataStr)) return exports.ALPHANUMERIC\n else if (Regex.testKanji(dataStr)) return exports.KANJI\n else return exports.BYTE\n}\n\n/**\n * Return mode name as string\n *\n * @param {Mode} mode Mode object\n * @returns {String} Mode name\n */\nexports.toString = function toString (mode) {\n if (mode && mode.id) return mode.id\n throw new Error('Invalid mode')\n}\n\n/**\n * Check if input param is a valid mode object\n *\n * @param {Mode} mode Mode object\n * @returns {Boolean} True if valid mode, false otherwise\n */\nexports.isValid = function isValid (mode) {\n return mode && mode.bit && mode.ccBits\n}\n\n/**\n * Get mode object from its name\n *\n * @param {String} string Mode name\n * @returns {Mode} Mode object\n */\nfunction fromString (string) {\n if (typeof string !== 'string') {\n throw new Error('Param is not a string')\n }\n\n const lcStr = string.toLowerCase()\n\n switch (lcStr) {\n case 'numeric':\n return exports.NUMERIC\n case 'alphanumeric':\n return exports.ALPHANUMERIC\n case 'kanji':\n return exports.KANJI\n case 'byte':\n return exports.BYTE\n default:\n throw new Error('Unknown mode: ' + string)\n }\n}\n\n/**\n * Returns mode from a value.\n * If value is not a valid mode, returns defaultValue\n *\n * @param {Mode|String} value Encoding mode\n * @param {Mode} defaultValue Fallback value\n * @return {Mode} Encoding mode\n */\nexports.from = function from (value, defaultValue) {\n if (exports.isValid(value)) {\n return value\n }\n\n try {\n return fromString(value)\n } catch (e) {\n return defaultValue\n }\n}\n","const Utils = require('./utils')\nconst ECCode = require('./error-correction-code')\nconst ECLevel = require('./error-correction-level')\nconst Mode = require('./mode')\nconst VersionCheck = require('./version-check')\n\n// Generator polynomial used to encode version information\nconst G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0)\nconst G18_BCH = Utils.getBCHDigit(G18)\n\nfunction getBestVersionForDataLength (mode, length, errorCorrectionLevel) {\n for (let currentVersion = 1; currentVersion <= 40; currentVersion++) {\n if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, mode)) {\n return currentVersion\n }\n }\n\n return undefined\n}\n\nfunction getReservedBitsCount (mode, version) {\n // Character count indicator + mode indicator bits\n return Mode.getCharCountIndicator(mode, version) + 4\n}\n\nfunction getTotalBitsFromDataArray (segments, version) {\n let totalBits = 0\n\n segments.forEach(function (data) {\n const reservedBits = getReservedBitsCount(data.mode, version)\n totalBits += reservedBits + data.getBitsLength()\n })\n\n return totalBits\n}\n\nfunction getBestVersionForMixedData (segments, errorCorrectionLevel) {\n for (let currentVersion = 1; currentVersion <= 40; currentVersion++) {\n const length = getTotalBitsFromDataArray(segments, currentVersion)\n if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, Mode.MIXED)) {\n return currentVersion\n }\n }\n\n return undefined\n}\n\n/**\n * Returns version number from a value.\n * If value is not a valid version, returns defaultValue\n *\n * @param {Number|String} value QR Code version\n * @param {Number} defaultValue Fallback value\n * @return {Number} QR Code version number\n */\nexports.from = function from (value, defaultValue) {\n if (VersionCheck.isValid(value)) {\n return parseInt(value, 10)\n }\n\n return defaultValue\n}\n\n/**\n * Returns how much data can be stored with the specified QR code version\n * and error correction level\n *\n * @param {Number} version QR Code version (1-40)\n * @param {Number} errorCorrectionLevel Error correction level\n * @param {Mode} mode Data mode\n * @return {Number} Quantity of storable data\n */\nexports.getCapacity = function getCapacity (version, errorCorrectionLevel, mode) {\n if (!VersionCheck.isValid(version)) {\n throw new Error('Invalid QR Code version')\n }\n\n // Use Byte mode as default\n if (typeof mode === 'undefined') mode = Mode.BYTE\n\n // Total codewords for this QR code version (Data + Error correction)\n const totalCodewords = Utils.getSymbolTotalCodewords(version)\n\n // Total number of error correction codewords\n const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)\n\n // Total number of data codewords\n const dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8\n\n if (mode === Mode.MIXED) return dataTotalCodewordsBits\n\n const usableBits = dataTotalCodewordsBits - getReservedBitsCount(mode, version)\n\n // Return max number of storable codewords\n switch (mode) {\n case Mode.NUMERIC:\n return Math.floor((usableBits / 10) * 3)\n\n case Mode.ALPHANUMERIC:\n return Math.floor((usableBits / 11) * 2)\n\n case Mode.KANJI:\n return Math.floor(usableBits / 13)\n\n case Mode.BYTE:\n default:\n return Math.floor(usableBits / 8)\n }\n}\n\n/**\n * Returns the minimum version needed to contain the amount of data\n *\n * @param {Segment} data Segment of data\n * @param {Number} [errorCorrectionLevel=H] Error correction level\n * @param {Mode} mode Data mode\n * @return {Number} QR Code version\n */\nexports.getBestVersionForData = function getBestVersionForData (data, errorCorrectionLevel) {\n let seg\n\n const ecl = ECLevel.from(errorCorrectionLevel, ECLevel.M)\n\n if (Array.isArray(data)) {\n if (data.length > 1) {\n return getBestVersionForMixedData(data, ecl)\n }\n\n if (data.length === 0) {\n return 1\n }\n\n seg = data[0]\n } else {\n seg = data\n }\n\n return getBestVersionForDataLength(seg.mode, seg.getLength(), ecl)\n}\n\n/**\n * Returns version information with relative error correction bits\n *\n * The version information is included in QR Code symbols of version 7 or larger.\n * It consists of an 18-bit sequence containing 6 data bits,\n * with 12 error correction bits calculated using the (18, 6) Golay code.\n *\n * @param {Number} version QR Code version\n * @return {Number} Encoded version info bits\n */\nexports.getEncodedBits = function getEncodedBits (version) {\n if (!VersionCheck.isValid(version) || version < 7) {\n throw new Error('Invalid QR Code version')\n }\n\n let d = version << 12\n\n while (Utils.getBCHDigit(d) - G18_BCH >= 0) {\n d ^= (G18 << (Utils.getBCHDigit(d) - G18_BCH))\n }\n\n return (version << 12) | d\n}\n","const Utils = require('./utils')\n\nconst G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0)\nconst G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1)\nconst G15_BCH = Utils.getBCHDigit(G15)\n\n/**\n * Returns format information with relative error correction bits\n *\n * The format information is a 15-bit sequence containing 5 data bits,\n * with 10 error correction bits calculated using the (15, 5) BCH code.\n *\n * @param {Number} errorCorrectionLevel Error correction level\n * @param {Number} mask Mask pattern\n * @return {Number} Encoded format information bits\n */\nexports.getEncodedBits = function getEncodedBits (errorCorrectionLevel, mask) {\n const data = ((errorCorrectionLevel.bit << 3) | mask)\n let d = data << 10\n\n while (Utils.getBCHDigit(d) - G15_BCH >= 0) {\n d ^= (G15 << (Utils.getBCHDigit(d) - G15_BCH))\n }\n\n // xor final data with mask pattern in order to ensure that\n // no combination of Error Correction Level and data mask pattern\n // will result in an all-zero data string\n return ((data << 10) | d) ^ G15_MASK\n}\n","const Mode = require('./mode')\n\nfunction NumericData (data) {\n this.mode = Mode.NUMERIC\n this.data = data.toString()\n}\n\nNumericData.getBitsLength = function getBitsLength (length) {\n return 10 * Math.floor(length / 3) + ((length % 3) ? ((length % 3) * 3 + 1) : 0)\n}\n\nNumericData.prototype.getLength = function getLength () {\n return this.data.length\n}\n\nNumericData.prototype.getBitsLength = function getBitsLength () {\n return NumericData.getBitsLength(this.data.length)\n}\n\nNumericData.prototype.write = function write (bitBuffer) {\n let i, group, value\n\n // The input data string is divided into groups of three digits,\n // and each group is converted to its 10-bit binary equivalent.\n for (i = 0; i + 3 <= this.data.length; i += 3) {\n group = this.data.substr(i, 3)\n value = parseInt(group, 10)\n\n bitBuffer.put(value, 10)\n }\n\n // If the number of input digits is not an exact multiple of three,\n // the final one or two digits are converted to 4 or 7 bits respectively.\n const remainingNum = this.data.length - i\n if (remainingNum > 0) {\n group = this.data.substr(i)\n value = parseInt(group, 10)\n\n bitBuffer.put(value, remainingNum * 3 + 1)\n }\n}\n\nmodule.exports = NumericData\n","const Mode = require('./mode')\n\n/**\n * Array of characters available in alphanumeric mode\n *\n * As per QR Code specification, to each character\n * is assigned a value from 0 to 44 which in this case coincides\n * with the array index\n *\n * @type {Array}\n */\nconst ALPHA_NUM_CHARS = [\n '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\n 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',\n ' ', '$', '%', '*', '+', '-', '.', '/', ':'\n]\n\nfunction AlphanumericData (data) {\n this.mode = Mode.ALPHANUMERIC\n this.data = data\n}\n\nAlphanumericData.getBitsLength = function getBitsLength (length) {\n return 11 * Math.floor(length / 2) + 6 * (length % 2)\n}\n\nAlphanumericData.prototype.getLength = function getLength () {\n return this.data.length\n}\n\nAlphanumericData.prototype.getBitsLength = function getBitsLength () {\n return AlphanumericData.getBitsLength(this.data.length)\n}\n\nAlphanumericData.prototype.write = function write (bitBuffer) {\n let i\n\n // Input data characters are divided into groups of two characters\n // and encoded as 11-bit binary codes.\n for (i = 0; i + 2 <= this.data.length; i += 2) {\n // The character value of the first character is multiplied by 45\n let value = ALPHA_NUM_CHARS.indexOf(this.data[i]) * 45\n\n // The character value of the second digit is added to the product\n value += ALPHA_NUM_CHARS.indexOf(this.data[i + 1])\n\n // The sum is then stored as 11-bit binary number\n bitBuffer.put(value, 11)\n }\n\n // If the number of input data characters is not a multiple of two,\n // the character value of the final character is encoded as a 6-bit binary number.\n if (this.data.length % 2) {\n bitBuffer.put(ALPHA_NUM_CHARS.indexOf(this.data[i]), 6)\n }\n}\n\nmodule.exports = AlphanumericData\n","const Mode = require('./mode')\n\nfunction ByteData (data) {\n this.mode = Mode.BYTE\n if (typeof (data) === 'string') {\n this.data = new TextEncoder().encode(data)\n } else {\n this.data = new Uint8Array(data)\n }\n}\n\nByteData.getBitsLength = function getBitsLength (length) {\n return length * 8\n}\n\nByteData.prototype.getLength = function getLength () {\n return this.data.length\n}\n\nByteData.prototype.getBitsLength = function getBitsLength () {\n return ByteData.getBitsLength(this.data.length)\n}\n\nByteData.prototype.write = function (bitBuffer) {\n for (let i = 0, l = this.data.length; i < l; i++) {\n bitBuffer.put(this.data[i], 8)\n }\n}\n\nmodule.exports = ByteData\n","const Mode = require('./mode')\nconst Utils = require('./utils')\n\nfunction KanjiData (data) {\n this.mode = Mode.KANJI\n this.data = data\n}\n\nKanjiData.getBitsLength = function getBitsLength (length) {\n return length * 13\n}\n\nKanjiData.prototype.getLength = function getLength () {\n return this.data.length\n}\n\nKanjiData.prototype.getBitsLength = function getBitsLength () {\n return KanjiData.getBitsLength(this.data.length)\n}\n\nKanjiData.prototype.write = function (bitBuffer) {\n let i\n\n // In the Shift JIS system, Kanji characters are represented by a two byte combination.\n // These byte values are shifted from the JIS X 0208 values.\n // JIS X 0208 gives details of the shift coded representation.\n for (i = 0; i < this.data.length; i++) {\n let value = Utils.toSJIS(this.data[i])\n\n // For characters with Shift JIS values from 0x8140 to 0x9FFC:\n if (value >= 0x8140 && value <= 0x9FFC) {\n // Subtract 0x8140 from Shift JIS value\n value -= 0x8140\n\n // For characters with Shift JIS values from 0xE040 to 0xEBBF\n } else if (value >= 0xE040 && value <= 0xEBBF) {\n // Subtract 0xC140 from Shift JIS value\n value -= 0xC140\n } else {\n throw new Error(\n 'Invalid SJIS character: ' + this.data[i] + '\\n' +\n 'Make sure your charset is UTF-8')\n }\n\n // Multiply most significant byte of result by 0xC0\n // and add least significant byte to product\n value = (((value >>> 8) & 0xff) * 0xC0) + (value & 0xff)\n\n // Convert result to a 13-bit binary string\n bitBuffer.put(value, 13)\n }\n}\n\nmodule.exports = KanjiData\n","'use strict';\n\n/******************************************************************************\n * Created 2008-08-19.\n *\n * Dijkstra path-finding functions. Adapted from the Dijkstar Python project.\n *\n * Copyright (C) 2008\n * Wyatt Baldwin <self@wyattbaldwin.com>\n * All rights reserved\n *\n * Licensed under the MIT license.\n *\n * http://www.opensource.org/licenses/mit-license.php\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *****************************************************************************/\nvar dijkstra = {\n single_source_shortest_paths: function(graph, s, d) {\n // Predecessor map for each node that has been encountered.\n // node ID => predecessor node ID\n var predecessors = {};\n\n // Costs of shortest paths from s to all nodes encountered.\n // node ID => cost\n var costs = {};\n costs[s] = 0;\n\n // Costs of shortest paths from s to all nodes encountered; differs from\n // `costs` in that it provides easy access to the node that currently has\n // the known shortest path from s.\n // XXX: Do we actually need both `costs` and `open`?\n var open = dijkstra.PriorityQueue.make();\n open.push(s, 0);\n\n var closest,\n u, v,\n cost_of_s_to_u,\n adjacent_nodes,\n cost_of_e,\n cost_of_s_to_u_plus_cost_of_e,\n cost_of_s_to_v,\n first_visit;\n while (!open.empty()) {\n // In the nodes remaining in graph that have a known cost from s,\n // find the node, u, that currently has the shortest path from s.\n closest = open.pop();\n u = closest.value;\n cost_of_s_to_u = closest.cost;\n\n // Get nodes adjacent to u...\n adjacent_nodes = graph[u] || {};\n\n // ...and explore the edges that connect u to those nodes, updating\n // the cost of the shortest paths to any or all of those nodes as\n // necessary. v is the node across the current edge from u.\n for (v in adjacent_nodes) {\n if (adjacent_nodes.hasOwnProperty(v)) {\n // Get the cost of the edge running from u to v.\n cost_of_e = adjacent_nodes[v];\n\n // Cost of s to u plus the cost of u to v across e--this is *a*\n // cost from s to v that may or may not be less than the current\n // known cost to v.\n cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e;\n\n // If we haven't visited v yet OR if the current known cost from s to\n // v is greater than the new cost we just found (cost of s to u plus\n // cost of u to v across e), update v's cost in the cost list and\n // update v's predecessor in the predecessor list (it's now u).\n cost_of_s_to_v = costs[v];\n first_visit = (typeof costs[v] === 'undefined');\n if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) {\n costs[v] = cost_of_s_to_u_plus_cost_of_e;\n open.push(v, cost_of_s_to_u_plus_cost_of_e);\n predecessors[v] = u;\n }\n }\n }\n }\n\n if (typeof d !== 'undefined' && typeof costs[d] === 'undefined') {\n var msg = ['Could not find a path from ', s, ' to ', d, '.'].join('');\n throw new Error(msg);\n }\n\n return predecessors;\n },\n\n extract_shortest_path_from_predecessor_list: function(predecessors, d) {\n var nodes = [];\n var u = d;\n var predecessor;\n while (u) {\n nodes.push(u);\n predecessor = predecessors[u];\n u = predecessors[u];\n }\n nodes.reverse();\n return nodes;\n },\n\n find_path: function(graph, s, d) {\n var predecessors = dijkstra.single_source_shortest_paths(graph, s, d);\n return dijkstra.extract_shortest_path_from_predecessor_list(\n predecessors, d);\n },\n\n /**\n * A very naive priority queue implementation.\n */\n PriorityQueue: {\n make: function (opts) {\n var T = dijkstra.PriorityQueue,\n t = {},\n key;\n opts = opts || {};\n for (key in T) {\n if (T.hasOwnProperty(key)) {\n t[key] = T[key];\n }\n }\n t.queue = [];\n t.sorter = opts.sorter || T.default_sorter;\n return t;\n },\n\n default_sorter: function (a, b) {\n return a.cost - b.cost;\n },\n\n /**\n * Add a new item to the queue and ensure the highest priority element\n * is at the front of the queue.\n */\n push: function (value, cost) {\n var item = {value: value, cost: cost};\n this.queue.push(item);\n this.queue.sort(this.sorter);\n },\n\n /**\n * Return the highest priority element in the queue.\n */\n pop: function () {\n return this.queue.shift();\n },\n\n empty: function () {\n return this.queue.length === 0;\n }\n }\n};\n\n\n// node.js module exports\nif (typeof module !== 'undefined') {\n module.exports = dijkstra;\n}\n","const Mode = require('./mode')\nconst NumericData = require('./numeric-data')\nconst AlphanumericData = require('./alphanumeric-data')\nconst ByteData = require('./byte-data')\nconst KanjiData = require('./kanji-data')\nconst Regex = require('./regex')\nconst Utils = require('./utils')\nconst dijkstra = require('dijkstrajs')\n\n/**\n * Returns UTF8 byte length\n *\n * @param {String} str Input string\n * @return {Number} Number of byte\n */\nfunction getStringByteLength (str) {\n return unescape(encodeURIComponent(str)).length\n}\n\n/**\n * Get a list of segments of the specified mode\n * from a string\n *\n * @param {Mode} mode Segment mode\n * @param {String} str String to process\n * @return {Array} Array of object with segments data\n */\nfunction getSegments (regex, mode, str) {\n const segments = []\n let result\n\n while ((result = regex.exec(str)) !== null) {\n segments.push({\n data: result[0],\n index: result.index,\n mode: mode,\n length: result[0].length\n })\n }\n\n return segments\n}\n\n/**\n * Extracts a series of segments with the appropriate\n * modes from a string\n *\n * @param {String} dataStr Input string\n * @return {Array} Array of object with segments data\n */\nfunction getSegmentsFromString (dataStr) {\n const numSegs = getSegments(Regex.NUMERIC, Mode.NUMERIC, dataStr)\n const alphaNumSegs = getSegments(Regex.ALPHANUMERIC, Mode.ALPHANUMERIC, dataStr)\n let byteSegs\n let kanjiSegs\n\n if (Utils.isKanjiModeEnabled()) {\n byteSegs = getSegments(Regex.BYTE, Mode.BYTE, dataStr)\n kanjiSegs = getSegments(Regex.KANJI, Mode.KANJI, dataStr)\n } else {\n byteSegs = getSegments(Regex.BYTE_KANJI, Mode.BYTE, dataStr)\n kanjiSegs = []\n }\n\n const segs = numSegs.concat(alphaNumSegs, byteSegs, kanjiSegs)\n\n return segs\n .sort(function (s1, s2) {\n return s1.index - s2.index\n })\n .map(function (obj) {\n return {\n data: obj.data,\n mode: obj.mode,\n length: obj.length\n }\n })\n}\n\n/**\n * Returns how many bits are needed to encode a string of\n * specified length with the specified mode\n *\n * @param {Number} length String length\n * @param {Mode} mode Segment mode\n * @return {Number} Bit length\n */\nfunction getSegmentBitsLength (length, mode) {\n switch (mode) {\n case Mode.NUMERIC:\n return NumericData.getBitsLength(length)\n case Mode.ALPHANUMERIC:\n return AlphanumericData.getBitsLength(length)\n case Mode.KANJI:\n return KanjiData.getBitsLength(length)\n case Mode.BYTE:\n return ByteData.getBitsLength(length)\n }\n}\n\n/**\n * Merges adjacent segments which have the same mode\n *\n * @param {Array} segs Array of object with segments data\n * @return {Array} Array of object with segments data\n */\nfunction mergeSegments (segs) {\n return segs.reduce(function (acc, curr) {\n const prevSeg = acc.length - 1 >= 0 ? acc[acc.length - 1] : null\n if (prevSeg && prevSeg.mode === curr.mode) {\n acc[acc.length - 1].data += curr.data\n return acc\n }\n\n acc.push(curr)\n return acc\n }, [])\n}\n\n/**\n * Generates a list of all possible nodes combination which\n * will be used to build a segments graph.\n *\n * Nodes are divided by groups. Each group will contain a list of all the modes\n * in which is possible to encode the given text.\n *\n * For example the text '12345' can be encoded as Numeric, Alphanumeric or Byte.\n * The group for '12345' will contain then 3 objects, one for each\n * possible encoding mode.\n *\n * Each node represents a possible segment.\n *\n * @param {Array} segs Array of object with segments data\n * @return {Array} Array of object with segments data\n */\nfunction buildNodes (segs) {\n const nodes = []\n for (let i = 0; i < segs.length; i++) {\n const seg = segs[i]\n\n switch (seg.mode) {\n case Mode.NUMERIC:\n nodes.push([seg,\n { data: seg.data, mode: Mode.ALPHANUMERIC, length: seg.length },\n { data: seg.data, mode: Mode.BYTE, length: seg.length }\n ])\n break\n case Mode.ALPHANUMERIC:\n nodes.push([seg,\n { data: seg.data, mode: Mode.BYTE, length: seg.length }\n ])\n break\n case Mode.KANJI:\n nodes.push([seg,\n { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }\n ])\n break\n case Mode.BYTE:\n nodes.push([\n { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }\n ])\n }\n }\n\n return nodes\n}\n\n/**\n * Builds a graph from a list of nodes.\n * All segments in each node group will be connected with all the segments of\n * the next group and so on.\n *\n * At each connection will be assigned a weight depending on the\n * segment's byte length.\n *\n * @param {Array} nodes Array of object with segments data\n * @param {Number} version QR Code version\n * @return {Object} Graph of all possible segments\n */\nfunction buildGraph (nodes, version) {\n const table = {}\n const graph = { start: {} }\n let prevNodeIds = ['start']\n\n for (let i = 0; i < nodes.length; i++) {\n const nodeGroup = nodes[i]\n const currentNodeIds = []\n\n for (let j = 0; j < nodeGroup.length; j++) {\n const node = nodeGroup[j]\n const key = '' + i + j\n\n currentNodeIds.push(key)\n table[key] = { node: node, lastCount: 0 }\n graph[key] = {}\n\n for (let n = 0; n < prevNodeIds.length; n++) {\n const prevNodeId = prevNodeIds[n]\n\n if (table[prevNodeId] && table[prevNodeId].node.mode === node.mode) {\n graph[prevNodeId][key] =\n getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) -\n getSegmentBitsLength(table[prevNodeId].lastCount, node.mode)\n\n table[prevNodeId].lastCount += node.length\n } else {\n if (table[prevNodeId]) table[prevNodeId].lastCount = node.length\n\n graph[prevNodeId][key] = getSegmentBitsLength(node.length, node.mode) +\n 4 + Mode.getCharCountIndicator(node.mode, version) // switch cost\n }\n }\n }\n\n prevNodeIds = currentNodeIds\n }\n\n for (let n = 0; n < prevNodeIds.length; n++) {\n graph[prevNodeIds[n]].end = 0\n }\n\n return { map: graph, table: table }\n}\n\n/**\n * Builds a segment from a specified data and mode.\n * If a mode is not specified, the more suitable will be used.\n *\n * @param {String} data Input data\n * @param {Mode | String} modesHint Data mode\n * @return {Segment} Segment\n */\nfunction buildSingleSegment (data, modesHint) {\n let mode\n const bestMode = Mode.getBestModeForData(data)\n\n mode = Mode.from(modesHint, bestMode)\n\n // Make sure data can be encoded\n if (mode !== Mode.BYTE && mode.bit < bestMode.bit) {\n throw new Error('\"' + data + '\"' +\n ' cannot be encoded with mode ' + Mode.toString(mode) +\n '.\\n Suggested mode is: ' + Mode.toString(bestMode))\n }\n\n // Use Mode.BYTE if Kanji support is disabled\n if (mode === Mode.KANJI && !Utils.isKanjiModeEnabled()) {\n mode = Mode.BYTE\n }\n\n switch (mode) {\n case Mode.NUMERIC:\n return new NumericData(data)\n\n case Mode.ALPHANUMERIC:\n return new AlphanumericData(data)\n\n case Mode.KANJI:\n return new KanjiData(data)\n\n case Mode.BYTE:\n return new ByteData(data)\n }\n}\n\n/**\n * Builds a list of segments from an array.\n * Array can contain Strings or Objects with segment's info.\n *\n * For each item which is a string, will be generated a segment with the given\n * string and the more appropriate encoding mode.\n *\n * For each item which is an object, will be generated a segment with the given\n * data and mode.\n * Objects must contain at least the property \"data\".\n * If property \"mode\" is not present, the more suitable mode will be used.\n *\n * @param {Array} array Array of objects with segments data\n * @return {Array} Array of Segments\n */\nexports.fromArray = function fromArray (array) {\n return array.reduce(function (acc, seg) {\n if (typeof seg === 'string') {\n acc.push(buildSingleSegment(seg, null))\n } else if (seg.data) {\n acc.push(buildSingleSegment(seg.data, seg.mode))\n }\n\n return acc\n }, [])\n}\n\n/**\n * Builds an optimized sequence of segments from a string,\n * which will produce the shortest possible bitstream.\n *\n * @param {String} data Input string\n * @param {Number} version QR Code version\n * @return {Array} Array of segments\n */\nexports.fromString = function fromString (data, version) {\n const segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled())\n\n const nodes = buildNodes(segs)\n const graph = buildGraph(nodes, version)\n const path = dijkstra.find_path(graph.map, 'start', 'end')\n\n const optimizedSegs = []\n for (let i = 1; i < path.length - 1; i++) {\n optimizedSegs.push(graph.table[path[i]].node)\n }\n\n return exports.fromArray(mergeSegments(optimizedSegs))\n}\n\n/**\n * Splits a string in various segments with the modes which\n * best represent their content.\n * The produced segments are far from being optimized.\n * The output of this function is only used to estimate a QR Code version\n * which may contain the data.\n *\n * @param {string} data Input string\n * @return {Array} Array of segments\n */\nexports.rawSplit = function rawSplit (data) {\n return exports.fromArray(\n getSegmentsFromString(data, Utils.isKanjiModeEnabled())\n )\n}\n","const Utils = require('./utils')\nconst ECLevel = require('./error-correction-level')\nconst BitBuffer = require('./bit-buffer')\nconst BitMatrix = require('./bit-matrix')\nconst AlignmentPattern = require('./alignment-pattern')\nconst FinderPattern = require('./finder-pattern')\nconst MaskPattern = require('./mask-pattern')\nconst ECCode = require('./error-correction-code')\nconst ReedSolomonEncoder = require('./reed-solomon-encoder')\nconst Version = require('./version')\nconst FormatInfo = require('./format-info')\nconst Mode = require('./mode')\nconst Segments = require('./segments')\n\n/**\n * QRCode for JavaScript\n *\n * modified by Ryan Day for nodejs support\n * Copyright (c) 2011 Ryan Day\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/mit-license.php\n *\n//---------------------------------------------------------------------\n// QRCode for JavaScript\n//\n// Copyright (c) 2009 Kazuhiko Arase\n//\n// URL: http://www.d-project.com/\n//\n// Licensed under the MIT license:\n// http://www.opensource.org/licenses/mit-license.php\n//\n// The word \"QR Code\" is registered trademark of\n// DENSO WAVE INCORPORATED\n// http://www.denso-wave.com/qrcode/faqpatent-e.html\n//\n//---------------------------------------------------------------------\n*/\n\n/**\n * Add finder patterns bits to matrix\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {Number} version QR Code version\n */\nfunction setupFinderPattern (matrix, version) {\n const size = matrix.size\n const pos = FinderPattern.getPositions(version)\n\n for (let i = 0; i < pos.length; i++) {\n const row = pos[i][0]\n const col = pos[i][1]\n\n for (let r = -1; r <= 7; r++) {\n if (row + r <= -1 || size <= row + r) continue\n\n for (let c = -1; c <= 7; c++) {\n if (col + c <= -1 || size <= col + c) continue\n\n if ((r >= 0 && r <= 6 && (c === 0 || c === 6)) ||\n (c >= 0 && c <= 6 && (r === 0 || r === 6)) ||\n (r >= 2 && r <= 4 && c >= 2 && c <= 4)) {\n matrix.set(row + r, col + c, true, true)\n } else {\n matrix.set(row + r, col + c, false, true)\n }\n }\n }\n }\n}\n\n/**\n * Add timing pattern bits to matrix\n *\n * Note: this function must be called before {@link setupAlignmentPattern}\n *\n * @param {BitMatrix} matrix Modules matrix\n */\nfunction setupTimingPattern (matrix) {\n const size = matrix.size\n\n for (let r = 8; r < size - 8; r++) {\n const value = r % 2 === 0\n matrix.set(r, 6, value, true)\n matrix.set(6, r, value, true)\n }\n}\n\n/**\n * Add alignment patterns bits to matrix\n *\n * Note: this function must be called after {@link setupTimingPattern}\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {Number} version QR Code version\n */\nfunction setupAlignmentPattern (matrix, version) {\n const pos = AlignmentPattern.getPositions(version)\n\n for (let i = 0; i < pos.length; i++) {\n const row = pos[i][0]\n const col = pos[i][1]\n\n for (let r = -2; r <= 2; r++) {\n for (let c = -2; c <= 2; c++) {\n if (r === -2 || r === 2 || c === -2 || c === 2 ||\n (r === 0 && c === 0)) {\n matrix.set(row + r, col + c, true, true)\n } else {\n matrix.set(row + r, col + c, false, true)\n }\n }\n }\n }\n}\n\n/**\n * Add version info bits to matrix\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {Number} version QR Code version\n */\nfunction setupVersionInfo (matrix, version) {\n const size = matrix.size\n const bits = Version.getEncodedBits(version)\n let row, col, mod\n\n for (let i = 0; i < 18; i++) {\n row = Math.floor(i / 3)\n col = i % 3 + size - 8 - 3\n mod = ((bits >> i) & 1) === 1\n\n matrix.set(row, col, mod, true)\n matrix.set(col, row, mod, true)\n }\n}\n\n/**\n * Add format info bits to matrix\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level\n * @param {Number} maskPattern Mask pattern reference value\n */\nfunction setupFormatInfo (matrix, errorCorrectionLevel, maskPattern) {\n const size = matrix.size\n const bits = FormatInfo.getEncodedBits(errorCorrectionLevel, maskPattern)\n let i, mod\n\n for (i = 0; i < 15; i++) {\n mod = ((bits >> i) & 1) === 1\n\n // vertical\n if (i < 6) {\n matrix.set(i, 8, mod, true)\n } else if (i < 8) {\n matrix.set(i + 1, 8, mod, true)\n } else {\n matrix.set(size - 15 + i, 8, mod, true)\n }\n\n // horizontal\n if (i < 8) {\n matrix.set(8, size - i - 1, mod, true)\n } else if (i < 9) {\n matrix.set(8, 15 - i - 1 + 1, mod, true)\n } else {\n matrix.set(8, 15 - i - 1, mod, true)\n }\n }\n\n // fixed module\n matrix.set(size - 8, 8, 1, true)\n}\n\n/**\n * Add encoded data bits to matrix\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {Uint8Array} data Data codewords\n */\nfunction setupData (matrix, data) {\n const size = matrix.size\n let inc = -1\n let row = size - 1\n let bitIndex = 7\n let byteIndex = 0\n\n for (let col = size - 1; col > 0; col -= 2) {\n if (col === 6) col--\n\n while (true) {\n for (let c = 0; c < 2; c++) {\n if (!matrix.isReserved(row, col - c)) {\n let dark = false\n\n if (byteIndex < data.length) {\n dark = (((data[byteIndex] >>> bitIndex) & 1) === 1)\n }\n\n matrix.set(row, col - c, dark)\n bitIndex--\n\n if (bitIndex === -1) {\n byteIndex++\n bitIndex = 7\n }\n }\n }\n\n row += inc\n\n if (row < 0 || size <= row) {\n row -= inc\n inc = -inc\n break\n }\n }\n }\n}\n\n/**\n * Create encoded codewords from data input\n *\n * @param {Number} version QR Code version\n * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level\n * @param {ByteData} data Data input\n * @return {Uint8Array} Buffer containing encoded codewords\n */\nfunction createData (version, errorCorrectionLevel, segments) {\n // Prepare data buffer\n const buffer = new BitBuffer()\n\n segments.forEach(function (data) {\n // prefix data with mode indicator (4 bits)\n buffer.put(data.mode.bit, 4)\n\n // Prefix data with character count indicator.\n // The character count indicator is a string of bits that represents the\n // number of characters that are being encoded.\n // The character count indicator must be placed after the mode indicator\n // and must be a certain number of bits long, depending on the QR version\n // and data mode\n // @see {@link Mode.getCharCountIndicator}.\n buffer.put(data.getLength(), Mode.getCharCountIndicator(data.mode, version))\n\n // add binary data sequence to buffer\n data.write(buffer)\n })\n\n // Calculate required number of bits\n const totalCodewords = Utils.getSymbolTotalCodewords(version)\n const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)\n const dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8\n\n // Add a terminator.\n // If the bit string is shorter than the total number of required bits,\n // a terminator of up to four 0s must be added to the right side of the string.\n // If the bit string is more than four bits shorter than the required number of bits,\n // add four 0s to the end.\n if (buffer.getLengthInBits() + 4 <= dataTotalCodewordsBits) {\n buffer.put(0, 4)\n }\n\n // If the bit string is fewer than four bits shorter, add only the number of 0s that\n // are needed to reach the required number of bits.\n\n // After adding the terminator, if the number of bits in the string is not a multiple of 8,\n // pad the string on the right with 0s to make the string's length a multiple of 8.\n while (buffer.getLengthInBits() % 8 !== 0) {\n buffer.putBit(0)\n }\n\n // Add pad bytes if the string is still shorter than the total number of required bits.\n // Extend the buffer to fill the data capacity of the symbol corresponding to\n // the Version and Error Correction Level by adding the Pad Codewords 11101100 (0xEC)\n // and 00010001 (0x11) alternately.\n const remainingByte = (dataTotalCodewordsBits - buffer.getLengthInBits()) / 8\n for (let i = 0; i < remainingByte; i++) {\n buffer.put(i % 2 ? 0x11 : 0xEC, 8)\n }\n\n return createCodewords(buffer, version, errorCorrectionLevel)\n}\n\n/**\n * Encode input data with Reed-Solomon and return codewords with\n * relative error correction bits\n *\n * @param {BitBuffer} bitBuffer Data to encode\n * @param {Number} version QR Code version\n * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level\n * @return {Uint8Array} Buffer containing encoded codewords\n */\nfunction createCodewords (bitBuffer, version, errorCorrectionLevel) {\n // Total codewords for this QR code version (Data + Error correction)\n const totalCodewords = Utils.getSymbolTotalCodewords(version)\n\n // Total number of error correction codewords\n const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)\n\n // Total number of data codewords\n const dataTotalCodewords = totalCodewords - ecTotalCodewords\n\n // Total number of blocks\n const ecTotalBlocks = ECCode.getBlocksCount(version, errorCorrectionLevel)\n\n // Calculate how many blocks each group should contain\n const blocksInGroup2 = totalCodewords % ecTotalBlocks\n const blocksInGroup1 = ecTotalBlocks - blocksInGroup2\n\n const totalCodewordsInGroup1 = Math.floor(totalCodewords / ecTotalBlocks)\n\n const dataCodewordsInGroup1 = Math.floor(dataTotalCodewords / ecTotalBlocks)\n const dataCodewordsInGroup2 = dataCodewordsInGroup1 + 1\n\n // Number of EC codewords is the same for both groups\n const ecCount = totalCodewordsInGroup1 - dataCodewordsInGroup1\n\n // Initialize a Reed-Solomon encoder with a generator polynomial of degree ecCount\n const rs = new ReedSolomonEncoder(ecCount)\n\n let offset = 0\n const dcData = new Array(ecTotalBlocks)\n const ecData = new Array(ecTotalBlocks)\n let maxDataSize = 0\n const buffer = new Uint8Array(bitBuffer.buffer)\n\n // Divide the buffer into the required number of blocks\n for (let b = 0; b < ecTotalBlocks; b++) {\n const dataSize = b < blocksInGroup1 ? dataCodewordsInGroup1 : dataCodewordsInGroup2\n\n // extract a block of data from buffer\n dcData[b] = buffer.slice(offset, offset + dataSize)\n\n // Calculate EC codewords for this data block\n ecData[b] = rs.encode(dcData[b])\n\n offset += dataSize\n maxDataSize = Math.max(maxDataSize, dataSize)\n }\n\n // Create final data\n // Interleave the data and error correction codewords from each block\n const data = new Uint8Array(totalCodewords)\n let index = 0\n let i, r\n\n // Add data codewords\n for (i = 0; i < maxDataSize; i++) {\n for (r = 0; r < ecTotalBlocks; r++) {\n if (i < dcData[r].length) {\n data[index++] = dcData[r][i]\n }\n }\n }\n\n // Apped EC codewords\n for (i = 0; i < ecCount; i++) {\n for (r = 0; r < ecTotalBlocks; r++) {\n data[index++] = ecData[r][i]\n }\n }\n\n return data\n}\n\n/**\n * Build QR Code symbol\n *\n * @param {String} data Input string\n * @param {Number} version QR Code version\n * @param {ErrorCorretionLevel} errorCorrectionLevel Error level\n * @param {MaskPattern} maskPattern Mask pattern\n * @return {Object} Object containing symbol data\n */\nfunction createSymbol (data, version, errorCorrectionLevel, maskPattern) {\n let segments\n\n if (Array.isArray(data)) {\n segments = Segments.fromArray(data)\n } else if (typeof data === 'string') {\n let estimatedVersion = version\n\n if (!estimatedVersion) {\n const rawSegments = Segments.rawSplit(data)\n\n // Estimate best version that can contain raw splitted segments\n estimatedVersion = Version.getBestVersionForData(rawSegments, errorCorrectionLevel)\n }\n\n // Build optimized segments\n // If estimated version is undefined, try with the highest version\n segments = Segments.fromString(data, estimatedVersion || 40)\n } else {\n throw new Error('Invalid data')\n }\n\n // Get the min version that can contain data\n const bestVersion = Version.getBestVersionForData(segments, errorCorrectionLevel)\n\n // If no version is found, data cannot be stored\n if (!bestVersion) {\n throw new Error('The amount of data is too big to be stored in a QR Code')\n }\n\n // If not specified, use min version as default\n if (!version) {\n version = bestVersion\n\n // Check if the specified version can contain the data\n } else if (version < bestVersion) {\n throw new Error('\\n' +\n 'The chosen QR Code version cannot contain this amount of data.\\n' +\n 'Minimum version required to store current data is: ' + bestVersion + '.\\n'\n )\n }\n\n const dataBits = createData(version, errorCorrectionLevel, segments)\n\n // Allocate matrix buffer\n const moduleCount = Utils.getSymbolSize(version)\n const modules = new BitMatrix(moduleCount)\n\n // Add function modules\n setupFinderPattern(modules, version)\n setupTimingPattern(modules)\n setupAlignmentPattern(modules, version)\n\n // Add temporary dummy bits for format info just to set them as reserved.\n // This is needed to prevent these bits from being masked by {@link MaskPattern.applyMask}\n // since the masking operation must be performed only on the encoding region.\n // These blocks will be replaced with correct values later in code.\n setupFormatInfo(modules, errorCorrectionLevel, 0)\n\n if (version >= 7) {\n setupVersionInfo(modules, version)\n }\n\n // Add data codewords\n setupData(modules, dataBits)\n\n if (isNaN(maskPattern)) {\n // Find best mask pattern\n maskPattern = MaskPattern.getBestMask(modules,\n setupFormatInfo.bind(null, modules, errorCorrectionLevel))\n }\n\n // Apply mask pattern\n MaskPattern.applyMask(maskPattern, modules)\n\n // Replace format info bits with correct values\n setupFormatInfo(modules, errorCorrectionLevel, maskPattern)\n\n return {\n modules: modules,\n version: version,\n errorCorrectionLevel: errorCorrectionLevel,\n maskPattern: maskPattern,\n segments: segments\n }\n}\n\n/**\n * QR Code\n *\n * @param {String | Array} data Input data\n * @param {Object} options Optional configurations\n * @param {Number} options.version QR Code version\n * @param {String} options.errorCorrectionLevel Error correction level\n * @param {Function} options.toSJISFunc Helper func to convert utf8 to sjis\n */\nexports.create = function create (data, options) {\n if (typeof data === 'undefined' || data === '') {\n throw new Error('No input text')\n }\n\n let errorCorrectionLevel = ECLevel.M\n let version\n let mask\n\n if (typeof options !== 'undefined') {\n // Use higher error correction level as default\n errorCorrectionLevel = ECLevel.from(options.errorCorrectionLevel, ECLevel.M)\n version = Version.from(options.version)\n mask = MaskPattern.from(options.maskPattern)\n\n if (options.toSJISFunc) {\n Utils.setToSJISFunction(options.toSJISFunc)\n }\n }\n\n return createSymbol(data, version, errorCorrectionLevel, mask)\n}\n","function hex2rgba (hex) {\n if (typeof hex === 'number') {\n hex = hex.toString()\n }\n\n if (typeof hex !== 'string') {\n throw new Error('Color should be defined as hex string')\n }\n\n let hexCode = hex.slice().replace('#', '').split('')\n if (hexCode.length < 3 || hexCode.length === 5 || hexCode.length > 8) {\n throw new Error('Invalid hex color: ' + hex)\n }\n\n // Convert from short to long form (fff -> ffffff)\n if (hexCode.length === 3 || hexCode.length === 4) {\n hexCode = Array.prototype.concat.apply([], hexCode.map(function (c) {\n return [c, c]\n }))\n }\n\n // Add default alpha value\n if (hexCode.length === 6) hexCode.push('F', 'F')\n\n const hexValue = parseInt(hexCode.join(''), 16)\n\n return {\n r: (hexValue >> 24) & 255,\n g: (hexValue >> 16) & 255,\n b: (hexValue >> 8) & 255,\n a: hexValue & 255,\n hex: '#' + hexCode.slice(0, 6).join('')\n }\n}\n\nexports.getOptions = function getOptions (options) {\n if (!options) options = {}\n if (!options.color) options.color = {}\n\n const margin = typeof options.margin === 'undefined' ||\n options.margin === null ||\n options.margin < 0\n ? 4\n : options.margin\n\n const width = options.width && options.width >= 21 ? options.width : undefined\n const scale = options.scale || 4\n\n return {\n width: width,\n scale: width ? 4 : scale,\n margin: margin,\n color: {\n dark: hex2rgba(options.color.dark || '#000000ff'),\n light: hex2rgba(options.color.light || '#ffffffff')\n },\n type: options.type,\n rendererOpts: options.rendererOpts || {}\n }\n}\n\nexports.getScale = function getScale (qrSize, opts) {\n return opts.width && opts.width >= qrSize + opts.margin * 2\n ? opts.width / (qrSize + opts.margin * 2)\n : opts.scale\n}\n\nexports.getImageWidth = function getImageWidth (qrSize, opts) {\n const scale = exports.getScale(qrSize, opts)\n return Math.floor((qrSize + opts.margin * 2) * scale)\n}\n\nexports.qrToImageData = function qrToImageData (imgData, qr, opts) {\n const size = qr.modules.size\n const data = qr.modules.data\n const scale = exports.getScale(size, opts)\n const symbolSize = Math.floor((size + opts.margin * 2) * scale)\n const scaledMargin = opts.margin * scale\n const palette = [opts.color.light, opts.color.dark]\n\n for (let i = 0; i < symbolSize; i++) {\n for (let j = 0; j < symbolSize; j++) {\n let posDst = (i * symbolSize + j) * 4\n let pxColor = opts.color.light\n\n if (i >= scaledMargin && j >= scaledMargin &&\n i < symbolSize - scaledMargin && j < symbolSize - scaledMargin) {\n const iSrc = Math.floor((i - scaledMargin) / scale)\n const jSrc = Math.floor((j - scaledMargin) / scale)\n pxColor = palette[data[iSrc * size + jSrc] ? 1 : 0]\n }\n\n imgData[posDst++] = pxColor.r\n imgData[posDst++] = pxColor.g\n imgData[posDst++] = pxColor.b\n imgData[posDst] = pxColor.a\n }\n }\n}\n","const Utils = require('./utils')\n\nfunction clearCanvas (ctx, canvas, size) {\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n if (!canvas.style) canvas.style = {}\n canvas.height = size\n canvas.width = size\n canvas.style.height = size + 'px'\n canvas.style.width = size + 'px'\n}\n\nfunction getCanvasElement () {\n try {\n return document.createElement('canvas')\n } catch (e) {\n throw new Error('You need to specify a canvas element')\n }\n}\n\nexports.render = function render (qrData, canvas, options) {\n let opts = options\n let canvasEl = canvas\n\n if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {\n opts = canvas\n canvas = undefined\n }\n\n if (!canvas) {\n canvasEl = getCanvasElement()\n }\n\n opts = Utils.getOptions(opts)\n const size = Utils.getImageWidth(qrData.modules.size, opts)\n\n const ctx = canvasEl.getContext('2d')\n const image = ctx.createImageData(size, size)\n Utils.qrToImageData(image.data, qrData, opts)\n\n clearCanvas(ctx, canvasEl, size)\n ctx.putImageData(image, 0, 0)\n\n return canvasEl\n}\n\nexports.renderToDataURL = function renderToDataURL (qrData, canvas, options) {\n let opts = options\n\n if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {\n opts = canvas\n canvas = undefined\n }\n\n if (!opts) opts = {}\n\n const canvasEl = exports.render(qrData, canvas, opts)\n\n const type = opts.type || 'image/png'\n const rendererOpts = opts.rendererOpts || {}\n\n return canvasEl.toDataURL(type, rendererOpts.quality)\n}\n","const Utils = require('./utils')\n\nfunction getColorAttrib (color, attrib) {\n const alpha = color.a / 255\n const str = attrib + '=\"' + color.hex + '\"'\n\n return alpha < 1\n ? str + ' ' + attrib + '-opacity=\"' + alpha.toFixed(2).slice(1) + '\"'\n : str\n}\n\nfunction svgCmd (cmd, x, y) {\n let str = cmd + x\n if (typeof y !== 'undefined') str += ' ' + y\n\n return str\n}\n\nfunction qrToPath (data, size, margin) {\n let path = ''\n let moveBy = 0\n let newRow = false\n let lineLength = 0\n\n for (let i = 0; i < data.length; i++) {\n const col = Math.floor(i % size)\n const row = Math.floor(i / size)\n\n if (!col && !newRow) newRow = true\n\n if (data[i]) {\n lineLength++\n\n if (!(i > 0 && col > 0 && data[i - 1])) {\n path += newRow\n ? svgCmd('M', col + margin, 0.5 + row + margin)\n : svgCmd('m', moveBy, 0)\n\n moveBy = 0\n newRow = false\n }\n\n if (!(col + 1 < size && data[i + 1])) {\n path += svgCmd('h', lineLength)\n lineLength = 0\n }\n } else {\n moveBy++\n }\n }\n\n return path\n}\n\nexports.render = function render (qrData, options, cb) {\n const opts = Utils.getOptions(options)\n const size = qrData.modules.size\n const data = qrData.modules.data\n const qrcodesize = size + opts.margin * 2\n\n const bg = !opts.color.light.a\n ? ''\n : '<path ' + getColorAttrib(opts.color.light, 'fill') +\n ' d=\"M0 0h' + qrcodesize + 'v' + qrcodesize + 'H0z\"/>'\n\n const path =\n '<path ' + getColorAttrib(opts.color.dark, 'stroke') +\n ' d=\"' + qrToPath(data, size, opts.margin) + '\"/>'\n\n const viewBox = 'viewBox=\"' + '0 0 ' + qrcodesize + ' ' + qrcodesize + '\"'\n\n const width = !opts.width ? '' : 'width=\"' + opts.width + '\" height=\"' + opts.width + '\" '\n\n const svgTag = '<svg xmlns=\"http://www.w3.org/2000/svg\" ' + width + viewBox + ' shape-rendering=\"crispEdges\">' + bg + path + '</svg>\\n'\n\n if (typeof cb === 'function') {\n cb(null, svgTag)\n }\n\n return svgTag\n}\n","\nconst canPromise = require('./can-promise')\n\nconst QRCode = require('./core/qrcode')\nconst CanvasRenderer = require('./renderer/canvas')\nconst SvgRenderer = require('./renderer/svg-tag.js')\n\nfunction renderCanvas (renderFunc, canvas, text, opts, cb) {\n const args = [].slice.call(arguments, 1)\n const argsNum = args.length\n const isLastArgCb = typeof args[argsNum - 1] === 'function'\n\n if (!isLastArgCb && !canPromise()) {\n throw new Error('Callback required as last argument')\n }\n\n if (isLastArgCb) {\n if (argsNum < 2) {\n throw new Error('Too few arguments provided')\n }\n\n if (argsNum === 2) {\n cb = text\n text = canvas\n canvas = opts = undefined\n } else if (argsNum === 3) {\n if (canvas.getContext && typeof cb === 'undefined') {\n cb = opts\n opts = undefined\n } else {\n cb = opts\n opts = text\n text = canvas\n canvas = undefined\n }\n }\n } else {\n if (argsNum < 1) {\n throw new Error('Too few arguments provided')\n }\n\n if (argsNum === 1) {\n text = canvas\n canvas = opts = undefined\n } else if (argsNum === 2 && !canvas.getContext) {\n opts = text\n text = canvas\n canvas = undefined\n }\n\n return new Promise(function (resolve, reject) {\n try {\n const data = QRCode.create(text, opts)\n resolve(renderFunc(data, canvas, opts))\n } catch (e) {\n reject(e)\n }\n })\n }\n\n try {\n const data = QRCode.create(text, opts)\n cb(null, renderFunc(data, canvas, opts))\n } catch (e) {\n cb(e)\n }\n}\n\nexports.create = QRCode.create\nexports.toCanvas = renderCanvas.bind(null, CanvasRenderer.render)\nexports.toDataURL = renderCanvas.bind(null, CanvasRenderer.renderToDataURL)\n\n// only svg for now.\nexports.toString = renderCanvas.bind(null, function (data, _, opts) {\n return SvgRenderer.render(data, opts)\n})\n","import type { PairingGrantSnapshot } from './report-wire.ts'\n\nexport const PAIRING_QR_TYPE = 'deeppilot-pairing'\nexport const PAIRING_QR_VERSION = 2\n\n/** `sha256:` + base64url(SHA-256(SubjectPublicKeyInfo DER)) of the LAN certificate. */\nexport const LAN_TLS_FINGERPRINT_PATTERN = /^sha256:[A-Za-z0-9_-]{43}$/\n\nexport function isLanTlsFingerprint(value: unknown): value is string {\n return typeof value === 'string' && LAN_TLS_FINGERPRINT_PATTERN.test(value)\n}\n\nexport interface PairingQRPayload {\n v: typeof PAIRING_QR_VERSION\n type: typeof PAIRING_QR_TYPE\n host: string\n code: string\n expiresAt: number\n audience: string\n /** Required for LAN hosts (self-signed TLS); absent for public-CA hosts. */\n tlsFingerprint?: string\n}\n\nexport interface PairingTarget {\n host: string\n kind: 'public' | 'lan'\n tlsFingerprint?: string\n}\n\n/**\n * Return every explicit DeepPilot transport target. LAN comes first because\n * it is private and lower latency; an online Funnel remains available as a\n * separate choice instead of silently replacing the local address. A LAN\n * listener without a certificate pin is never offered: the app could not\n * trust it.\n */\nexport function selectPairingTargets(\n local: { phase: string; endpoints: string[]; tlsFingerprint?: string },\n remote: { phase: string; publicURL?: string },\n): PairingTarget[] {\n const targets: PairingTarget[] = []\n if (local.phase === 'online' && isLanTlsFingerprint(local.tlsFingerprint)) {\n for (const host of local.endpoints) {\n if (validTargetHost(host)) targets.push({ host, kind: 'lan', tlsFingerprint: local.tlsFingerprint })\n }\n }\n if (remote.phase === 'online' && remote.publicURL && validTargetHost(remote.publicURL)) {\n targets.push({ host: remote.publicURL, kind: 'public' })\n }\n const seen = new Set<string>()\n return targets.filter(({ host }) => !seen.has(host) && seen.add(host))\n}\n\n/** Only encrypted transports are ever offered to the app. */\nconst TARGET_PROTOCOLS = ['https:', 'wss:']\n\nfunction validTargetHost(value: string): boolean {\n try {\n const parsed = new URL(value)\n return TARGET_PROTOCOLS.includes(parsed.protocol)\n && parsed.hostname !== ''\n && parsed.username === ''\n && parsed.password === ''\n } catch {\n return false\n }\n}\n\n/** Encode a short-lived, single-use pairing grant without URL credentials. */\nexport function encodePairingQRPayload(host: string, grant: PairingGrantSnapshot, tlsFingerprint?: string): string {\n assertPairingInput(host, grant, tlsFingerprint)\n const payload: PairingQRPayload = {\n v: PAIRING_QR_VERSION,\n type: PAIRING_QR_TYPE,\n host: host.trim(),\n code: grant.code.trim(),\n expiresAt: grant.expiresAt,\n audience: grant.audience,\n ...(tlsFingerprint !== undefined ? { tlsFingerprint } : {}),\n }\n return JSON.stringify(payload)\n}\n\n/**\n * One copyable string carrying everything the app needs to pair: host, the\n * single-use code, the LAN certificate pin and the host audience.\n *\n * Users copy this once instead of moving three separate values, and the app\n * accepts it from the paste field, a deep link and (from this version on) the\n * QR code. Field names are short because the whole string ends up in a QR code\n * and in a text field: `h` host, `c` code, `f` fingerprint, `a` audience,\n * `e` expiry in milliseconds.\n */\nexport function encodePairingLink(host: string, grant: PairingGrantSnapshot, tlsFingerprint?: string): string {\n assertPairingInput(host, grant, tlsFingerprint)\n const params = new URLSearchParams()\n params.set('h', host.trim())\n params.set('c', grant.code.trim())\n if (tlsFingerprint !== undefined) params.set('f', tlsFingerprint)\n params.set('a', grant.audience)\n params.set('e', String(grant.expiresAt))\n // URLSearchParams percent-encodes the host and the pin; the app decodes them.\n return `${PAIRING_LINK_PREFIX}?${params.toString()}`\n}\n\n/** `deeppilot://pair` — the deep-link route the iOS app parses. */\nexport const PAIRING_LINK_PREFIX = 'deeppilot://pair'\n\nfunction assertPairingInput(host: string, grant: PairingGrantSnapshot, tlsFingerprint?: string): void {\n if (!validTargetHost(host.trim())) {\n throw new TypeError('pairing QR requires a valid HTTPS/WSS host')\n }\n if (grant.code.trim().length < 32 || !Number.isInteger(grant.expiresAt) || grant.expiresAt <= Date.now()) {\n throw new TypeError('pairing grant is invalid or expired')\n }\n if (!grant.audience.startsWith('deeppilot:')) throw new TypeError('pairing audience is invalid')\n if (tlsFingerprint !== undefined && !isLanTlsFingerprint(tlsFingerprint)) {\n throw new TypeError('pairing TLS fingerprint is invalid')\n }\n}\n","import type { PairingTarget } from '../pairing-qr.ts'\nimport type { PairingGrantSnapshot } from '../report-wire.ts'\n\n/**\n * Pure state machine for the pairing panel on the plugin settings page.\n *\n * It lives outside the React component because the behaviour that used to be\n * wrong is exactly the kind a renderer cannot show in a unit test: switching\n * between the LAN and public address must keep the panel open and re-issue a\n * grant for the newly selected host instead of collapsing it.\n */\nexport interface PairingPanelState {\n /** Address the visible grant was issued for; null = panel closed. */\n target: PairingTarget | null\n busy: boolean\n grant: PairingGrantSnapshot | null\n link: string | null\n qrDataURL: string | null\n message: string\n /** Transient \"copied\" feedback; cleared after a moment. */\n notice: string\n /** Monotonic id; only the newest in-flight issue may render a result. */\n requestId: number\n}\n\nexport const initialPairingPanelState: PairingPanelState = {\n target: null,\n busy: false,\n grant: null,\n link: null,\n qrDataURL: null,\n message: '',\n notice: '',\n requestId: 0,\n}\n\nexport type PairingPanelAction =\n /** \"Show QR code\" or switching address while the panel is open. */\n | { type: 'show'; target: PairingTarget; requestId: number }\n | { type: 'issued'; requestId: number; grant: PairingGrantSnapshot; link: string; qrDataURL: string }\n | { type: 'failed'; requestId: number; message: string }\n /** Clipboard result for the pairing string. */\n | { type: 'notice'; message: string }\n | { type: 'dismissNotice' }\n /** \"Hide QR code\": explicit close, or the single-use code expired. */\n | { type: 'close'; message?: string }\n\nexport function pairingPanelReduce(state: PairingPanelState, action: PairingPanelAction): PairingPanelState {\n switch (action.type) {\n case 'show':\n // Keep the panel open for the new target: the grant, the link and the QR\n // all belong to the previous address and are cleared until the new one\n // arrives, so a stale string can never be paired against a new host.\n return {\n target: action.target,\n busy: true,\n grant: null,\n link: null,\n qrDataURL: null,\n message: '',\n notice: '',\n requestId: action.requestId,\n }\n case 'issued':\n if (action.requestId !== state.requestId) return state\n return {\n ...state,\n busy: false,\n grant: action.grant,\n link: action.link,\n qrDataURL: action.qrDataURL,\n }\n case 'failed':\n if (action.requestId !== state.requestId) return state\n // The message stays on the now-empty panel so the user reads it where the\n // QR code was, instead of the panel silently collapsing.\n return { ...state, busy: false, grant: null, link: null, qrDataURL: null, message: action.message }\n case 'notice':\n return { ...state, notice: action.message }\n case 'dismissNotice':\n return state.notice === '' ? state : { ...state, notice: '' }\n case 'close':\n // Invalidate in-flight work so a late grant cannot reopen the panel.\n return { ...initialPairingPanelState, requestId: state.requestId + 1, message: action.message ?? '' }\n }\n}\n\nexport interface PairingPanelView {\n /** The panel (QR + pairing info, or its error state) is on screen. */\n open: boolean\n /** An issue is in flight; the toggle is disabled while it runs. */\n busy: boolean\n /** The last issue failed; the panel shows the message and a retry hint. */\n failed: boolean\n /** Button label key: show / generating / hide. */\n action: 'pair.qrShow' | 'pair.qrGenerating' | 'pair.qrHide'\n /** Address the visible payload pairs against; null while closed or loading. */\n target: PairingTarget | null\n link: string | null\n qrDataURL: string | null\n message: string\n notice: string\n}\n\nexport function pairingPanelView(state: PairingPanelState): PairingPanelView {\n // A target stays selected for as long as the panel is open, including the\n // failed state where there is a message to read but no payload yet.\n const open = state.target !== null\n return {\n open,\n busy: state.busy,\n failed: open && !state.busy && state.grant === null,\n action: state.busy ? 'pair.qrGenerating' : state.target === null ? 'pair.qrShow' : 'pair.qrHide',\n target: state.target,\n link: state.link,\n qrDataURL: state.qrDataURL,\n message: state.message,\n notice: state.notice,\n }\n}\n","export const DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE = 8\nexport const MAX_FUNNEL_CONNECTIONS_PER_SOURCE = 16\n\nexport function normalizeFunnelConnectionLimit(value: unknown): number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= MAX_FUNNEL_CONNECTIONS_PER_SOURCE\n ? value\n : DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE\n}\n","export const DEFAULT_LOCAL_PORT = 3098\nexport const MIN_LOCAL_PORT = 1024\nexport const MAX_LOCAL_PORT = 65_535\n\nexport function normalizeLocalPort(value: unknown): number {\n return typeof value === 'number'\n && Number.isInteger(value)\n && value >= MIN_LOCAL_PORT\n && value <= MAX_LOCAL_PORT\n ? value\n : DEFAULT_LOCAL_PORT\n}\n\n/** The LAN listener is TLS-only, so every advertised endpoint is `https://`. */\nexport function localEndpointURLs(addresses: readonly string[], port: number): string[] {\n const normalizedPort = normalizeLocalPort(port)\n return [...new Set(addresses)].map((address) => `https://${address}:${normalizedPort}`)\n}\n\nexport function localListenError(error: unknown, port: number): string {\n const code = (error as NodeJS.ErrnoException | undefined)?.code\n if (code === 'EADDRINUSE') return `local port ${port} is already in use`\n if (code === 'EACCES') return `permission denied while opening local port ${port}`\n return error instanceof Error ? error.message : String(error)\n}\n","/**\n * 设置页依赖的**接口**:一次声明页面消费的全部东西,外加一道归一化 seam。\n *\n * 迁移前页面签名是 `props: Record<string, any>`,20 个依赖全凭运行期 typeof\n * 守卫;拼错一个名字不会编译报错,只会在页面上变成一条诊断行。宿主注入面\n * (client/index.ts 的 inject 字面量)与页面之间没有任何类型级链接。\n *\n * 这里做两件事:\n * 1. `SettingsPageProps` 把 20 个依赖的类型钉住,宿主面与页面共享它;\n * 2. `normalizeSettingsPageProps` 是唯一的 seam:校验一次、缺省补齐、把\n * 「宿主没给全」折算成诊断列表与能力集合。页面体里不再出现任何 typeof。\n *\n * 关于 React 的硬约束:7 个 `useDeepPilot*` 是 hook,必须留在组件体内无条件\n * 调用,不能包进普通函数。因此 hook 缺失时在这里换成**模块级 fallback hook**\n * (引用恒定,React 不会把它当作 hook 顺序变化),缺省态与今天页面内的分支\n * 逐一对齐。\n */\n\nimport type {\n DebugState,\n EnabledState,\n LocalEnabledState,\n LocalPortState,\n PageState,\n RemoteConnectionLimitState,\n RemoteEnabledState,\n} from './index.ts'\nimport type { DeepPilotReport, PairingGrantSnapshot, PushTestResult, RelayTestResult } from '../report-wire.ts'\nimport type { Translate } from './i18n.ts'\nimport { DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE } from '../funnel-policy.ts'\nimport { DEFAULT_LOCAL_PORT } from '../local-policy.ts'\n\n/** 一个选择器 hook:页面传恒等选择器取整份状态。 */\nexport type Selector<S> = (select: (state: S) => S) => S\n\nexport type ReportSelector = Selector<PageState>\nexport type EnabledSelector = Selector<EnabledState>\nexport type LocalEnabledSelector = Selector<LocalEnabledState>\nexport type LocalPortSelector = Selector<LocalPortState>\nexport type RemoteEnabledSelector = Selector<RemoteEnabledState>\nexport type RemoteLimitSelector = Selector<RemoteConnectionLimitState>\nexport type DebugSelector = Selector<DebugState>\n\n/** 页面真正用到的报告字段(诊断与统计块都只读这些)。 */\nexport type SettingsReport = DeepPilotReport\n\nexport interface SettingsPageProps {\n // ---------- hooks(恒为函数:缺失时由 seam 换成 fallback) ----------\n useDeepPilotReport: ReportSelector\n useDeepPilotEnabled: EnabledSelector\n useDeepPilotLocalEnabled: LocalEnabledSelector\n useDeepPilotLocalPort: LocalPortSelector\n useDeepPilotRemoteEnabled: RemoteEnabledSelector\n useDeepPilotRemoteConnectionLimit: RemoteLimitSelector\n useDeepPilotDebug: DebugSelector\n // ---------- 可选函数:在位情况见 `can` ----------\n refresh?: () => void\n beginPairing?: () => Promise<PairingGrantSnapshot>\n revokeDevice?: (deviceId: string) => Promise<unknown>\n setDeviceName?: (deviceId: string, customName: string | null) => Promise<unknown>\n testRelay?: () => Promise<RelayTestResult>\n testPush?: () => Promise<PushTestResult>\n setDeepPilotEnabled?: (enabled: boolean) => unknown\n setDeepPilotLocalEnabled?: (enabled: boolean) => unknown\n setDeepPilotLocalPort?: (port: number) => Promise<unknown> | unknown\n setDeepPilotRemoteEnabled?: (enabled: boolean) => unknown\n setDeepPilotRemoteConnectionLimit?: (limit: number) => Promise<unknown> | unknown\n setDeepPilotDebug?: (enabled: boolean) => unknown\n /** 绑定的翻译函数;页面所有文案都经它。 */\n t: Translate\n}\n\n/** 可选能力的名字:页面的行为分支读集合,不再 typeof。 */\nexport type SettingsCapability =\n | 'refresh'\n | 'beginPairing'\n | 'revokeDevice'\n | 'setDeviceName'\n | 'testRelay'\n | 'testPush'\n | 'setEnabled'\n | 'setLocalEnabled'\n | 'setLocalPort'\n | 'setRemoteEnabled'\n | 'setRemoteLimit'\n | 'setDebug'\n\nexport interface SettingsPageSurface {\n props: SettingsPageProps\n can: ReadonlySet<SettingsCapability>\n /** 已翻译的诊断行,顺序与迁移前页面内的 diag[] 一致。 */\n diagnostics: string[]\n /** 报告 hook 整个缺失:统计/配对/系统区块整段跳过。 */\n reportHookMissing: boolean\n}\n\n// ---------- hook 缺失时的缺省态 ----------\n\nexport const MISSING_REPORT_HOOK: ReportSelector = () => ({ status: 'loading', report: null, message: '' })\nexport const MISSING_ENABLED_HOOK: EnabledSelector = () => ({ status: 'unavailable', enabled: true })\nexport const MISSING_LOCAL_ENABLED_HOOK: LocalEnabledSelector = () => ({ status: 'unavailable', enabled: true })\nexport const MISSING_LOCAL_PORT_HOOK: LocalPortSelector = () => ({ status: 'unavailable', value: DEFAULT_LOCAL_PORT })\nexport const MISSING_REMOTE_ENABLED_HOOK: RemoteEnabledSelector = () => ({ status: 'unavailable', enabled: false })\nexport const MISSING_REMOTE_LIMIT_HOOK: RemoteLimitSelector = () => ({ status: 'unavailable', value: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE })\nexport const MISSING_DEBUG_HOOK: DebugSelector = () => ({ status: 'unavailable', enabled: false })\n\n/** 诊断行的 key,集中在此便于对账(tests/settings-props.test.ts 逐条断言)。 */\nconst DIAG_KEY = {\n reportHook: 'diag.missingReportHook',\n enabledHook: 'diag.missingEnabledHook',\n localEnabledHook: 'diag.missingLocalEnabledHook',\n localPortHook: 'diag.missingLocalPortHook',\n remoteEnabledHook: 'diag.missingRemoteEnabledHook',\n remoteLimitHook: 'diag.missingRemoteLimitHook',\n debugHook: 'diag.missingDebugHook',\n refresh: 'diag.missingRefresh',\n reveal: 'diag.missingReveal',\n rotate: 'diag.missingRotate',\n rename: 'diag.missingRename',\n testRelay: 'diag.missingTestRelay',\n testPush: 'diag.missingTestPush',\n setEnabled: 'diag.missingSetEnabled',\n setLocal: 'diag.missingSetLocal',\n setLocalPort: 'diag.missingSetLocalPort',\n setRemote: 'diag.missingSetRemote',\n setRemoteLimit: 'diag.missingSetRemoteLimit',\n setDebug: 'diag.missingSetDebug',\n settingsUnavailable: 'diag.settingsUnavailable',\n} as const\n\nconst CAPABILITY_BY_PROP: ReadonlyArray<[SettingsCapability, keyof SettingsPageProps]> = [\n ['refresh', 'refresh'],\n ['beginPairing', 'beginPairing'],\n ['revokeDevice', 'revokeDevice'],\n ['setDeviceName', 'setDeviceName'],\n ['testRelay', 'testRelay'],\n ['testPush', 'testPush'],\n ['setEnabled', 'setDeepPilotEnabled'],\n ['setLocalEnabled', 'setDeepPilotLocalEnabled'],\n ['setLocalPort', 'setDeepPilotLocalPort'],\n ['setRemoteEnabled', 'setDeepPilotRemoteEnabled'],\n ['setRemoteLimit', 'setDeepPilotRemoteConnectionLimit'],\n ['setDebug', 'setDeepPilotDebug'],\n]\n\nconst isFn = (value: unknown): value is (...args: never[]) => unknown => typeof value === 'function'\n\n/**\n * 把宿主注入的原始对象归一化成页面可消费的面。\n *\n * 逐项复刻迁移前页面内的行为:hook 缺失换 fallback 并记诊断;函数缺失则该\n * 能力不进 `can` 并记诊断;诊断顺序与原先的 `diag[]` 完全一致(宿主过期时\n * 用户看到的技术诊断因此一字不差)。\n */\nexport function normalizeSettingsPageProps(raw: unknown): SettingsPageSurface {\n const source = (raw ?? {}) as Record<string, unknown>\n const t = typeof source.t === 'function' ? (source.t as Translate) : ((key: string) => key)\n const diagnostics: string[] = []\n const can = new Set<SettingsCapability>()\n\n const useReport = isFn(source.useDeepPilotReport) ? (source.useDeepPilotReport as ReportSelector) : MISSING_REPORT_HOOK\n const useEnabled = isFn(source.useDeepPilotEnabled) ? (source.useDeepPilotEnabled as EnabledSelector) : MISSING_ENABLED_HOOK\n const useLocalEnabled = isFn(source.useDeepPilotLocalEnabled) ? (source.useDeepPilotLocalEnabled as LocalEnabledSelector) : MISSING_LOCAL_ENABLED_HOOK\n const useLocalPort = isFn(source.useDeepPilotLocalPort) ? (source.useDeepPilotLocalPort as LocalPortSelector) : MISSING_LOCAL_PORT_HOOK\n const useRemoteEnabled = isFn(source.useDeepPilotRemoteEnabled) ? (source.useDeepPilotRemoteEnabled as RemoteEnabledSelector) : MISSING_REMOTE_ENABLED_HOOK\n const useRemoteLimit = isFn(source.useDeepPilotRemoteConnectionLimit) ? (source.useDeepPilotRemoteConnectionLimit as RemoteLimitSelector) : MISSING_REMOTE_LIMIT_HOOK\n const useDebug = isFn(source.useDeepPilotDebug) ? (source.useDeepPilotDebug as DebugSelector) : MISSING_DEBUG_HOOK\n\n // 顺序必须与迁移前页面内的 diag[] 一致,否则宿主过期时用户看到的技术诊断会变样。\n if (!isFn(source.useDeepPilotReport)) diagnostics.push(t(DIAG_KEY.reportHook))\n if (!isFn(source.useDeepPilotEnabled)) diagnostics.push(t(DIAG_KEY.enabledHook))\n if (!isFn(source.refresh)) diagnostics.push(t(DIAG_KEY.refresh))\n if (!isFn(source.beginPairing)) diagnostics.push(t(DIAG_KEY.reveal))\n if (!isFn(source.revokeDevice)) diagnostics.push(t(DIAG_KEY.rotate))\n if (!isFn(source.setDeviceName)) diagnostics.push(t(DIAG_KEY.rename))\n if (!isFn(source.testRelay)) diagnostics.push(t(DIAG_KEY.testRelay))\n if (!isFn(source.testPush)) diagnostics.push(t(DIAG_KEY.testPush))\n if (!isFn(source.setDeepPilotEnabled)) diagnostics.push(t(DIAG_KEY.setEnabled))\n if (!isFn(source.useDeepPilotLocalEnabled)) diagnostics.push(t(DIAG_KEY.localEnabledHook))\n if (!isFn(source.useDeepPilotLocalPort)) diagnostics.push(t(DIAG_KEY.localPortHook))\n if (!isFn(source.setDeepPilotLocalEnabled)) diagnostics.push(t(DIAG_KEY.setLocal))\n if (!isFn(source.setDeepPilotLocalPort)) diagnostics.push(t(DIAG_KEY.setLocalPort))\n if (!isFn(source.useDeepPilotRemoteEnabled)) diagnostics.push(t(DIAG_KEY.remoteEnabledHook))\n if (!isFn(source.setDeepPilotRemoteEnabled)) diagnostics.push(t(DIAG_KEY.setRemote))\n if (!isFn(source.useDeepPilotRemoteConnectionLimit)) diagnostics.push(t(DIAG_KEY.remoteLimitHook))\n if (!isFn(source.setDeepPilotRemoteConnectionLimit)) diagnostics.push(t(DIAG_KEY.setRemoteLimit))\n if (!isFn(source.useDeepPilotDebug)) diagnostics.push(t(DIAG_KEY.debugHook))\n if (!isFn(source.setDeepPilotDebug)) diagnostics.push(t(DIAG_KEY.setDebug))\n\n for (const [capability, prop] of CAPABILITY_BY_PROP) {\n if (isFn(source[prop])) can.add(capability)\n }\n\n const props: SettingsPageProps = {\n useDeepPilotReport: useReport,\n useDeepPilotEnabled: useEnabled,\n useDeepPilotLocalEnabled: useLocalEnabled,\n useDeepPilotLocalPort: useLocalPort,\n useDeepPilotRemoteEnabled: useRemoteEnabled,\n useDeepPilotRemoteConnectionLimit: useRemoteLimit,\n useDeepPilotDebug: useDebug,\n t: t as Translate,\n refresh: isFn(source.refresh) ? (source.refresh as () => void) : undefined,\n beginPairing: isFn(source.beginPairing) ? (source.beginPairing as () => Promise<PairingGrantSnapshot>) : undefined,\n revokeDevice: isFn(source.revokeDevice) ? (source.revokeDevice as (deviceId: string) => Promise<unknown>) : undefined,\n setDeviceName: isFn(source.setDeviceName) ? (source.setDeviceName as SettingsPageProps['setDeviceName']) : undefined,\n testRelay: isFn(source.testRelay) ? (source.testRelay as () => Promise<RelayTestResult>) : undefined,\n testPush: isFn(source.testPush) ? (source.testPush as () => Promise<PushTestResult>) : undefined,\n setDeepPilotEnabled: isFn(source.setDeepPilotEnabled) ? (source.setDeepPilotEnabled as SettingsPageProps['setDeepPilotEnabled']) : undefined,\n setDeepPilotLocalEnabled: isFn(source.setDeepPilotLocalEnabled) ? (source.setDeepPilotLocalEnabled as SettingsPageProps['setDeepPilotLocalEnabled']) : undefined,\n setDeepPilotLocalPort: isFn(source.setDeepPilotLocalPort) ? (source.setDeepPilotLocalPort as SettingsPageProps['setDeepPilotLocalPort']) : undefined,\n setDeepPilotRemoteEnabled: isFn(source.setDeepPilotRemoteEnabled) ? (source.setDeepPilotRemoteEnabled as SettingsPageProps['setDeepPilotRemoteEnabled']) : undefined,\n setDeepPilotRemoteConnectionLimit: isFn(source.setDeepPilotRemoteConnectionLimit) ? (source.setDeepPilotRemoteConnectionLimit as SettingsPageProps['setDeepPilotRemoteConnectionLimit']) : undefined,\n setDeepPilotDebug: isFn(source.setDeepPilotDebug) ? (source.setDeepPilotDebug as SettingsPageProps['setDeepPilotDebug']) : undefined,\n }\n\n return { props, can, diagnostics, reportHookMissing: !isFn(source.useDeepPilotReport) }\n}\n","/**\n * 设置页的 view model:把原先住在渲染函数里的三块逻辑变成可单测的纯模块。\n *\n * 迁移前 `settings-page.ts` 是一个 1059 行的组件,funnel phase → {dot, label}、\n端口/连接数草稿的编辑与合法性、serviceStatus 派生全在渲染函数里,没有任何\n直接测试。这里按 pairing-panel.ts 的形状把它们拆成 state / action / reduce /\nview 四件套——shape 与该先例一致,但**不继承它唯一的泄漏**:view model 只返回\n语义值,i18n key 的映射留在页面(措辞归页面,测试不跟着措辞漂)。\n */\n\nimport type { DeepPilotReport } from '../report-wire.ts'\nimport { DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE, MAX_FUNNEL_CONNECTIONS_PER_SOURCE } from '../funnel-policy.ts'\nimport { DEFAULT_LOCAL_PORT, MAX_LOCAL_PORT, MIN_LOCAL_PORT } from '../local-policy.ts'\n\n// ---------- 传输 phase ----------\n\n/** 点位的视觉状态。空串 = 无点位。 */\nexport type Dot = '' | ' pbb-dotWarn' | ' pbb-dotOk' | ' pbb-dotBad'\n\n/** phase 的语义标签;页面负责把它映射成 i18n key。 */\nexport type RemotePhaseLabel =\n | 'disabled' | 'starting' | 'login_required' | 'online' | 'error' | 'unavailable' | 'stopped'\nexport type LocalPhaseLabel = 'disabled' | 'starting' | 'online' | 'error' | 'stopped'\n\nexport interface PhaseMeta<L extends string> {\n dot: Dot\n label: L\n}\n\nexport const REMOTE_PHASE_META: Record<DeepPilotReport['remote']['phase'], PhaseMeta<RemotePhaseLabel>> = {\n disabled: { dot: '', label: 'disabled' },\n starting: { dot: ' pbb-dotWarn', label: 'starting' },\n login_required: { dot: ' pbb-dotWarn', label: 'login_required' },\n online: { dot: ' pbb-dotOk', label: 'online' },\n error: { dot: ' pbb-dotBad', label: 'error' },\n unavailable: { dot: ' pbb-dotBad', label: 'unavailable' },\n stopped: { dot: '', label: 'stopped' },\n}\n\nexport const LOCAL_PHASE_META: Record<DeepPilotReport['local']['phase'], PhaseMeta<LocalPhaseLabel>> = {\n disabled: { dot: '', label: 'disabled' },\n starting: { dot: ' pbb-dotWarn', label: 'starting' },\n online: { dot: ' pbb-dotOk', label: 'online' },\n error: { dot: ' pbb-dotBad', label: 'error' },\n stopped: { dot: '', label: 'stopped' },\n}\n\n/** 从点位反推「需要注意 / 已在线」——原先页面用字符串 includes 猜类名。 */\nexport function dotState(dot: string | undefined): { attention: boolean; online: boolean } {\n return {\n attention: dot?.includes('pbb-dotBad') === true,\n online: dot?.includes('pbb-dotOk') === true,\n }\n}\n\n/** 服务状态:总开关未就绪 / 已关闭 / 需要注意 / 在线 / 仍在起。 */\nexport type ServiceStatusKind = 'loading' | 'off' | 'attention' | 'ready'\n\nexport interface ServiceStatus {\n kind: ServiceStatusKind\n dot: Dot\n}\n\nexport function serviceStatus(input: {\n enabled: boolean\n switchReady: boolean\n localDot: string | undefined\n remoteDot: string | undefined\n}): ServiceStatus {\n const local = dotState(input.localDot)\n const remote = dotState(input.remoteDot)\n const attention = local.attention || remote.attention\n const online = local.online || remote.online\n // 「两个传输都关闭」不是「仍在读取」:disabled / stopped 的 phase 本来\n // 就没有点位(dot 为空串),此前会落到 loading,页面永久显示「正在读取\n // 状态…」。没有点位且开关就绪时状态已经确定,按未启用展示。\n const hasSignal = (dot: string | undefined): boolean => dot !== undefined && dot !== ''\n const anySignal = hasSignal(input.localDot) || hasSignal(input.remoteDot)\n const kind: ServiceStatusKind = !input.switchReady\n ? 'loading'\n : !input.enabled\n ? 'off'\n : attention\n ? 'attention'\n : online\n ? 'ready'\n : anySignal\n ? 'loading'\n : 'off'\n const dot: Dot = !input.enabled || (!attention && !online && !anySignal)\n ? ''\n : attention\n ? ' pbb-dotBad'\n : online\n ? ' pbb-dotOk'\n : ' pbb-dotWarn'\n return { kind, dot }\n}\n\n// ---------- 数字草稿(本地端口 / Funnel 连接数) ----------\n\n/** 一个数字草稿的合法区间。 */\nexport interface NumericRange {\n min: number\n max: number\n fallback: number\n}\n\nexport const LOCAL_PORT_RANGE: NumericRange = { min: MIN_LOCAL_PORT, max: MAX_LOCAL_PORT, fallback: DEFAULT_LOCAL_PORT }\nexport const REMOTE_LIMIT_RANGE: NumericRange = {\n min: 1,\n max: MAX_FUNNEL_CONNECTIONS_PER_SOURCE,\n fallback: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE,\n}\n\nexport interface NumericDraftState {\n /** 输入框里的原文;空串表示尚未编辑。 */\n draft: string\n /** 上一次应用结果的消息;空串表示无消息。 */\n message: string\n /** 消息是否表示失败(页面据此染红)。 */\n failed: boolean\n}\n\nexport type NumericDraftAction =\n /** 输入框变化。 */\n | { type: 'edit'; draft: string }\n /** 外部值变化:把草稿同步回最新值。 */\n | { type: 'sync'; value: number }\n /** 应用完成:清空消息(也用于四秒后的自动清除)。 */\n | { type: 'applied' }\n /** 应用成功并给出提示文案。 */\n | { type: 'succeeded'; message: string }\n | { type: 'failed'; message: string }\n\nexport function initialNumericDraft(range: NumericRange): NumericDraftState {\n return { draft: String(range.fallback), message: '', failed: false }\n}\n\nexport function numericDraftReduce(state: NumericDraftState, action: NumericDraftAction, range: NumericRange): NumericDraftState {\n switch (action.type) {\n case 'edit':\n return { ...state, draft: action.draft }\n case 'sync':\n return { ...state, draft: String(action.value), message: '', failed: false }\n case 'applied':\n return { ...state, message: '', failed: false }\n case 'succeeded':\n return { ...state, message: action.message, failed: false }\n case 'failed':\n return { ...state, message: action.message, failed: true }\n }\n}\n\nexport interface NumericDraftView {\n /** 解析出的值;非法时为 NaN。 */\n value: number\n valid: boolean\n /** 与当前生效值相同(应用按钮据此禁用)。 */\n unchanged: boolean\n}\n\nexport function numericDraftView(state: NumericDraftState, current: number, range: NumericRange): NumericDraftView {\n const value = Number(state.draft)\n const valid = Number.isInteger(value) && value >= range.min && value <= range.max\n return { value, valid, unchanged: valid && value === current }\n}\n\n// ---------- 设备列表 ----------\n\n/** 页面渲染设备行所需的字段(report.devices 的子集)。 */\nexport interface SettingsDevice {\n deviceId: string\n deviceName: string\n customName?: string\n revokedAt?: number\n appVersion?: string\n fingerprint?: string\n lastSeenTs?: number\n}\n\n/** 已撤销的设备不展示。 */\nexport function visibleDevices(report: DeepPilotReport | null): SettingsDevice[] {\n return (report?.devices ?? []).filter((device) => device.revokedAt === undefined)\n}\n\n/** 设备展示名:自定义名优先,都没有则空串(兜底文案归页面)。 */\nexport function deviceLabel(device: { deviceName: string; customName?: string }): string {\n return (device.customName ?? device.deviceName).trim()\n}\n","import { createElement as h, useEffect, useId, useReducer, useRef, useState } from 'react'\nimport { Button, Switch } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { DeviceActions } from './device-actions.ts'\nimport { settingsIcon } from './settings-icons.ts'\nimport * as QRCode from 'qrcode/lib/browser.js'\nimport type { DeepPilotReport, PairingGrantSnapshot, PushTestResult, RelayTestResult, ReportDiagnosticFailure } from '../report-wire.ts'\nimport { encodePairingLink, selectPairingTargets, type PairingTarget } from '../pairing-qr.ts'\nimport { initialPairingPanelState, pairingPanelReduce, pairingPanelView } from './pairing-panel.ts'\nimport { translateWith as t } from './i18n.ts'\nimport {\n normalizeSettingsPageProps,\n type SettingsCapability,\n type SettingsPageProps,\n} from './settings-props.ts'\nimport type { PageState } from './index.ts'\nimport { DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE } from '../funnel-policy.ts'\nimport { DEFAULT_LOCAL_PORT } from '../local-policy.ts'\nimport {\n LOCAL_PHASE_META,\n LOCAL_PORT_RANGE,\n REMOTE_LIMIT_RANGE,\n REMOTE_PHASE_META,\n deviceLabel as deviceLabelOf,\n initialNumericDraft,\n numericDraftReduce,\n numericDraftView,\n serviceStatus,\n visibleDevices as visibleDevicesOf,\n type LocalPhaseLabel,\n type NumericDraftAction,\n type NumericDraftState,\n type RemotePhaseLabel,\n} from './settings-view-models.ts'\n\ntype T = (key: string, vars?: Readonly<Record<string, unknown>>) => string\n\n/** 中文结论由调用处提供,原始上游信息统一放入括号,保留排查依据。 */\nconst errorDetails = (error: unknown): string =>\n '(' + (error instanceof Error ? error.message : String(error)) + ')'\n\n/** 通道标题旁的短状态;完整端点和参数放入对应的连接选项。 */\nconst CHANNEL_STATE_KEY: Record<RemotePhaseLabel | LocalPhaseLabel, string> = {\n disabled: 'channel.state.disabled',\n starting: 'channel.state.starting',\n login_required: 'channel.state.login_required',\n online: 'channel.state.online',\n error: 'channel.state.error',\n unavailable: 'channel.state.unavailable',\n stopped: 'channel.state.stopped',\n}\n/** 服务状态 → i18n key。 */\nconst SERVICE_STATUS_KEY = {\n loading: 'status.loading',\n off: 'status.off',\n attention: 'status.attention',\n ready: 'status.ready',\n} as const\n\n/** Chevron icon (linear, currentColor). CSS rotates it 90° while its owner is\n * expanded, so collapsed always means \"points right, more content behind\". */\nconst ChevronIcon = (): any =>\n h('svg', {\n className: 'pbb-chevIcon',\n viewBox: '0 0 16 16',\n width: 12,\n height: 12,\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 1.5,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n 'aria-hidden': true,\n },\n h('path', { d: 'M6 3.5 10.5 8 6 12.5' }),\n )\n\n/** 诊断结果使用线性 SVG,与页面其余图标保持一致。 */\nconst CheckIcon = (): any =>\n h('svg', {\n viewBox: '0 0 16 16', width: 12, height: 12, fill: 'none', stroke: 'currentColor',\n strokeWidth: 1.6, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true,\n }, h('path', { d: 'M3.5 8.5 6.5 11.5 12.5 4.5' }))\n\nconst CrossIcon = (): any =>\n h('svg', {\n viewBox: '0 0 16 16', width: 12, height: 12, fill: 'none', stroke: 'currentColor',\n strokeWidth: 1.6, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true,\n }, h('path', { d: 'M4.5 4.5 11.5 11.5' }), h('path', { d: 'M11.5 4.5 4.5 11.5' }))\n\n/** One result line: SVG mark + text; the mark carries the pass/fail state. */\nconst resultRow = (ok: boolean, text: string, key: string): any =>\n h('p', { className: 'pbb-diag pbb-resultRow', key },\n h('span', { className: 'pbb-resultIcon' + (ok ? '' : ' pbb-resultIconBad') },\n ok ? CheckIcon() : CrossIcon()),\n h('span', null, text))\n\n/** 最近在线只细化到分钟:秒和年份对判断设备是否还连着没有意义。 */\nfunction formatLastSeen(ts: number | undefined): string {\n if (ts === undefined || !Number.isFinite(ts) || ts <= 0) return '—'\n return new Date(ts).toLocaleString(undefined, {\n month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit',\n })\n}\n\nasync function writeClipboard(t: T, value: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(value)\n return\n } catch {\n // Some embedded browsers expire user activation while a remote call is in\n // flight. Keep a synchronous fallback scoped to a short-lived textarea.\n }\n const textarea = document.createElement('textarea')\n textarea.value = value\n textarea.style.position = 'fixed'\n textarea.style.opacity = '0'\n document.body.appendChild(textarea)\n textarea.select()\n const copied = document.execCommand('copy')\n textarea.remove()\n if (!copied) throw new Error(t('clipboard.rejected'))\n}\n\n/**\n * Slot component: hooks come from the slot renderer, named use<Key>.\n *\n * 组件的接口是 `SettingsPageProps`(见 settings-props.ts):宿主注入面与页面\n * 共享同一份类型。这里只做一次归一化,之后全程消费类型化对象——页面里不再\n * 出现任何 typeof 守卫,也不再自己拼诊断行。\n */\nexport function DeepPilotSettingsPage(rawProps: Record<string, any>): any {\n const surface = normalizeSettingsPageProps(rawProps)\n const props: SettingsPageProps = surface.props\n const can = (capability: SettingsCapability): boolean => surface.can.has(capability)\n\n const [remoteLimitDraft, dispatchRemoteLimitDraft] = useReducer(\n (state: NumericDraftState, action: NumericDraftAction) => numericDraftReduce(state, action, REMOTE_LIMIT_RANGE),\n initialNumericDraft(REMOTE_LIMIT_RANGE),\n )\n const [localPortDraft, dispatchLocalPortDraft] = useReducer(\n (state: NumericDraftState, action: NumericDraftAction) => numericDraftReduce(state, action, LOCAL_PORT_RANGE),\n initialNumericDraft(LOCAL_PORT_RANGE),\n )\n const [selectedPairingHost, setSelectedPairingHost] = useState<string | null>(null)\n const [pairingOpen, setPairingOpen] = useState(false)\n const pageId = useId()\n const localOptionsId = pageId + '-local'\n const remoteOptionsId = pageId + '-remote'\n const troubleshootingId = pageId + '-troubleshooting'\n const systemId = pageId + '-system'\n const pairingId = pageId + '-pairing'\n const [pairingPanel, dispatchPairingPanel] = useReducer(pairingPanelReduce, initialPairingPanelState)\n const qrRequestId = useRef(0)\n const [troubleshootingOpen, setTroubleshootingOpen] = useState(false)\n const [relayTestBusy, setRelayTestBusy] = useState(false)\n const [relayTestResult, setRelayTestResult] = useState<RelayTestResult | null>(null)\n const [relayTestError, setRelayTestError] = useState('')\n const [pushTestBusy, setPushTestBusy] = useState(false)\n const [pushTestResult, setPushTestResult] = useState<PushTestResult | null>(null)\n const [pushTestError, setPushTestError] = useState('')\n const [deviceBusy, setDeviceBusy] = useState<string | null>(null)\n const [deviceMessage, setDeviceMessage] = useState('')\n const [editingDeviceId, setEditingDeviceId] = useState<string | null>(null)\n const [deviceNameDraft, setDeviceNameDraft] = useState('')\n /** 复制诊断信息的结果提示;failed 决定是否染红。 */\n const [diagnosticsCopy, setDiagnosticsCopy] = useState<{ message: string; failed: boolean }>({ message: '', failed: false })\n // 两条通道的「连接选项」都默认收起:端口、上限、帮助都是低频设置,不占首屏。\n const [localOptionsOpen, setLocalOptionsOpen] = useState(false)\n const [remoteOptionsOpen, setRemoteOptionsOpen] = useState(false)\n const [systemOpen, setSystemOpen] = useState(false)\n const [armedRevokeDeviceId, setArmedRevokeDeviceId] = useState<string | null>(null)\n const [nowMs, setNowMs] = useState(() => Date.now())\n\n useEffect(() => {\n if (!can('refresh')) return\n const refresh = props.refresh!\n refresh()\n const timer = globalThis.setInterval(() => refresh(), 3_000)\n return () => globalThis.clearInterval(timer)\n }, [props.refresh])\n\n const sendPushTest = (): void => {\n if (pushTestBusy) return\n if (!can('testPush')) {\n setPushTestError(t(props.t, 'push.staleHost'))\n return\n }\n setTroubleshootingOpen(true)\n setPushTestBusy(true)\n setPushTestError('')\n void props.testPush!().then((result: PushTestResult) => {\n setPushTestResult(result)\n setPushTestBusy(false)\n }, (error: unknown) => {\n setPushTestError(t(props.t, 'push.pushFailed') + errorDetails(error))\n setPushTestBusy(false)\n })\n }\n\n const runRelayTest = (): void => {\n if (relayTestBusy) return\n if (!can('testRelay')) {\n setRelayTestError(t(props.t, 'push.staleHostRelay'))\n return\n }\n setTroubleshootingOpen(true)\n setRelayTestBusy(true)\n setRelayTestError('')\n void props.testRelay!().then((result: RelayTestResult) => {\n setRelayTestResult(result)\n setRelayTestBusy(false)\n }, (error: unknown) => {\n setRelayTestError(t(props.t, 'push.relayBad') + errorDetails(error))\n setRelayTestBusy(false)\n })\n }\n\n // 两个草稿的「应用结果」消息四秒后自动消失。reducer 的 applied 动作把消息\n // 清空,因此这里只需要一个触发器。\n useEffect(() => {\n if (remoteLimitDraft.message === '') return\n const timer = globalThis.setTimeout(() => dispatchRemoteLimitDraft({ type: 'applied' }), 4_000)\n return () => globalThis.clearTimeout(timer)\n }, [remoteLimitDraft.message])\n\n useEffect(() => {\n if (localPortDraft.message === '') return\n const timer = globalThis.setTimeout(() => dispatchLocalPortDraft({ type: 'applied' }), 4_000)\n return () => globalThis.clearTimeout(timer)\n }, [localPortDraft.message])\n\n useEffect(() => {\n if (pairingPanel.grant === null) return\n // The panel carries a single-use code, so it must not outlive the grant.\n const remaining = Math.max(0, pairingPanel.grant.expiresAt - Date.now())\n const timer = globalThis.setTimeout(() => {\n dispatchPairingPanel({ type: 'close', message: t(props.t, 'pair.qrExpired') })\n }, remaining)\n return () => globalThis.clearTimeout(timer)\n }, [pairingPanel.grant])\n\n useEffect(() => {\n if (!pairingPanel.notice) return\n const timer = globalThis.setTimeout(() => dispatchPairingPanel({ type: 'dismissNotice' }), 2_500)\n return () => globalThis.clearTimeout(timer)\n }, [pairingPanel.notice])\n\n // hook 必须在组件体内无条件调用(React 规则):归一化 seam 已保证它们永远是\n // 函数——宿主没给时换成引用恒定的 fallback,缺省态与迁移前逐项对齐。\n // 它们仍是整个渲染里唯一可能抛的点(宿主 store 自己炸),因此保留渲染异常\n // 诊断:与迁移前一样折算成一行 diag.renderError 并把详情块展开。\n const diag = surface.diagnostics\n let failed = surface.reportHookMissing\n const readHooks = (): void => {\n const reportState = props.useDeepPilotReport((s: PageState) => s)\n hooks.report = reportState.report\n if (reportState.status === 'error' && reportState.message) {\n diag.push(t(props.t, 'diag.reportFailed') + errorDetails(reportState.message))\n failed = true\n }\n const enabledState = props.useDeepPilotEnabled((s) => s)\n hooks.enabled = enabledState.enabled\n hooks.switchReady = enabledState.status === 'ready'\n if (enabledState.status === 'unavailable') diag.push(t(props.t, 'diag.settingsUnavailable'))\n const localEnabledState = props.useDeepPilotLocalEnabled((s) => s)\n hooks.localEnabled = localEnabledState.enabled\n hooks.localSwitchReady = localEnabledState.status === 'ready'\n const localPortState = props.useDeepPilotLocalPort((s) => s)\n hooks.localPort = localPortState.value\n hooks.localPortReady = localPortState.status === 'ready'\n const remoteEnabledState = props.useDeepPilotRemoteEnabled((s) => s)\n hooks.remoteEnabled = remoteEnabledState.enabled\n hooks.remoteSwitchReady = remoteEnabledState.status === 'ready'\n const remoteLimitState = props.useDeepPilotRemoteConnectionLimit((s) => s)\n hooks.remoteConnectionLimit = remoteLimitState.value\n hooks.remoteConnectionLimitReady = remoteLimitState.status === 'ready'\n const debugState = props.useDeepPilotDebug((s) => s)\n hooks.debugEnabled = debugState.enabled\n hooks.debugSwitchReady = debugState.status === 'ready'\n }\n const hooks: {\n report: DeepPilotReport | null\n enabled: boolean\n switchReady: boolean\n localEnabled: boolean\n localSwitchReady: boolean\n localPort: number\n localPortReady: boolean\n remoteEnabled: boolean\n remoteSwitchReady: boolean\n remoteConnectionLimit: number\n remoteConnectionLimitReady: boolean\n debugEnabled: boolean\n debugSwitchReady: boolean\n } = {\n report: null, enabled: true, switchReady: false,\n localEnabled: true, localSwitchReady: false,\n localPort: DEFAULT_LOCAL_PORT, localPortReady: false,\n remoteEnabled: false, remoteSwitchReady: false,\n remoteConnectionLimit: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE, remoteConnectionLimitReady: false,\n debugEnabled: false, debugSwitchReady: false,\n }\n try {\n readHooks()\n } catch (error) {\n diag.push(t(props.t, 'diag.renderError') + errorDetails(error))\n failed = true\n }\n const report = hooks.report\n const enabled = hooks.enabled\n const switchReady = hooks.switchReady\n const localEnabled = hooks.localEnabled\n const localSwitchReady = hooks.localSwitchReady\n const localPort = hooks.localPort\n const localPortReady = hooks.localPortReady\n const remoteEnabled = hooks.remoteEnabled\n const remoteSwitchReady = hooks.remoteSwitchReady\n const remoteConnectionLimit = hooks.remoteConnectionLimit\n const remoteConnectionLimitReady = hooks.remoteConnectionLimitReady\n const debugEnabled = hooks.debugEnabled\n const debugSwitchReady = hooks.debugSwitchReady\n\n useEffect(() => {\n dispatchRemoteLimitDraft({ type: 'sync', value: remoteConnectionLimit })\n }, [remoteConnectionLimit])\n\n useEffect(() => {\n dispatchLocalPortDraft({ type: 'sync', value: localPort })\n }, [localPort])\n\n const localPortView = numericDraftView(localPortDraft, localPort, LOCAL_PORT_RANGE)\n const remoteLimitView = numericDraftView(remoteLimitDraft, remoteConnectionLimit, REMOTE_LIMIT_RANGE)\n const applyLocalPort = (): void => {\n if (!localPortView.valid || !can('setLocalPort')) {\n dispatchLocalPortDraft({ type: 'failed', message: t(props.t, 'local.portInvalid') })\n return\n }\n dispatchLocalPortDraft({ type: 'applied' })\n void Promise.resolve(props.setDeepPilotLocalPort!(localPortView.value)).then(() => {\n dispatchLocalPortDraft({ type: 'succeeded', message: t(props.t, 'local.portApplied') })\n }, (error: unknown) => {\n dispatchLocalPortDraft({\n type: 'failed',\n message: t(props.t, 'local.portFailed') + errorDetails(error),\n })\n })\n }\n\n const applyRemoteLimit = (): void => {\n if (!remoteLimitView.valid || !can('setRemoteLimit')) {\n dispatchRemoteLimitDraft({ type: 'failed', message: t(props.t, 'remote.limitInvalid') })\n return\n }\n dispatchRemoteLimitDraft({ type: 'applied' })\n void Promise.resolve(props.setDeepPilotRemoteConnectionLimit!(remoteLimitView.value)).then(() => {\n dispatchRemoteLimitDraft({ type: 'succeeded', message: t(props.t, 'remote.limitApplied') })\n }, (error: unknown) => {\n dispatchRemoteLimitDraft({\n type: 'failed',\n message: t(props.t, 'remote.limitFailed') + errorDetails(error),\n })\n })\n }\n\n const pairingTargets = report === null ? [] : selectPairingTargets(report.local, report.remote)\n const pairingTarget = pairingTargets.find(({ host }) => host === selectedPairingHost) ?? pairingTargets[0] ?? null\n const panel = pairingPanelView(pairingPanel)\n\n /**\n * Issue a grant and render the panel for one explicit target.\n *\n * The target is a parameter rather than component state on purpose: a click\n * handler must not depend on whether React has already re-rendered with the\n * newly selected host. A grant is bound to the host it was issued for, so\n * switching between LAN and public always mints a fresh one.\n */\n const showPairingQR = (target: PairingTarget): void => {\n if (!can('beginPairing')) return\n // Each request carries a token: a fast LAN/public switch can leave two\n // issues in flight, and only the newest may render its grant.\n const requestId = qrRequestId.current + 1\n qrRequestId.current = requestId\n dispatchPairingPanel({ type: 'show', target, requestId })\n void (props.beginPairing!() as Promise<PairingGrantSnapshot>)\n .then(async (grant: PairingGrantSnapshot) => {\n // The QR code and the copy field carry the same short link, so the app\n // accepts it from the camera and from the paste field alike.\n const link = encodePairingLink(target.host, grant, target.tlsFingerprint)\n return {\n grant,\n link,\n svg: await QRCode.toString(link, { type: 'svg', errorCorrectionLevel: 'M', margin: 2, width: 512 }),\n }\n })\n .then(({ grant, link, svg }) => {\n if (qrRequestId.current !== requestId) return\n dispatchPairingPanel({\n type: 'issued',\n requestId,\n grant,\n link,\n qrDataURL: 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg),\n })\n }, (error: unknown) => {\n if (qrRequestId.current !== requestId) return\n dispatchPairingPanel({\n type: 'failed',\n requestId,\n message: t(props.t, 'pair.qrFailed') + errorDetails(error),\n })\n })\n }\n\n const hidePairingQR = (): void => {\n // Invalidate any in-flight issue so a late response cannot reopen the panel.\n qrRequestId.current += 1\n dispatchPairingPanel({ type: 'close' })\n }\n\n const copyPairingInfo = (): void => {\n const link = pairingPanel.link\n if (link === null) return\n dispatchPairingPanel({ type: 'notice', message: '' })\n void writeClipboard(props.t as T, link).then(() => {\n dispatchPairingPanel({ type: 'notice', message: t(props.t, 'pair.infoCopyDone') })\n }, (error: unknown) => {\n dispatchPairingPanel({\n type: 'notice',\n message: t(props.t, 'pair.infoCopyFailed') + errorDetails(error),\n })\n })\n }\n\n // 运行信息只在系统信息展开后显示;TLS 指纹属于局域网连接选项。\n const advancedRows: any[] = []\n if (report !== null) {\n advancedRows.push(\n h('div', { className: 'pbb-runtimeRow', key: 'proto' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.protocolVersion')),\n h('span', { className: 'pbb-value' }, 'v' + String(report.protocolVersion)))),\n h('div', { className: 'pbb-runtimeRow', key: 'server' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.serverVersion')),\n h('span', { className: 'pbb-value' }, report.serverVersion))),\n h('div', { className: 'pbb-runtimeRow', key: 'path' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.identityPath')),\n h('span', { className: 'pbb-value' }, report.identityPath))),\n h('div', { className: 'pbb-runtimeRow', key: 'buffer' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.bufferMax')),\n h('span', { className: 'pbb-value' }, String(report.historyBufferMax) + t(props.t, 'advanced.frames')))),\n )\n }\n\n // Revocation is armed in-page first (delete, then confirm delete); it\n // used to be a window.confirm dialog. Disconnect semantics are\n // unchanged: the device is revoked immediately on confirmation.\n const revokeDevice = (deviceId: string, _name: string): void => {\n void _name\n if (!can('revokeDevice')) return\n setDeviceBusy(deviceId)\n setDeviceMessage('')\n void props.revokeDevice!(deviceId).then(() => {\n setDeviceMessage(t(props.t, 'devices.revoked'))\n }, (error: unknown) => {\n setDeviceMessage(t(props.t, 'devices.revokeFailed') + errorDetails(error))\n }).finally(() => {\n setDeviceBusy(null)\n })\n }\n\n const deviceLabel = (device: { deviceName: string; customName?: string }): string =>\n deviceLabelOf(device) || t(props.t, 'devices.unnamed')\n\n const beginDeviceRename = (device: { deviceId: string; deviceName: string; customName?: string }): void => {\n setArmedRevokeDeviceId(null)\n setEditingDeviceId(device.deviceId)\n setDeviceNameDraft(device.customName ?? device.deviceName)\n setDeviceMessage('')\n }\n\n const cancelDeviceRename = (): void => {\n setEditingDeviceId(null)\n setDeviceNameDraft('')\n setDeviceMessage('')\n }\n\n const saveDeviceName = (deviceId: string): void => {\n if (!can('setDeviceName')) return\n const normalized = deviceNameDraft.trim()\n if (normalized.length > 64) {\n setDeviceMessage(t(props.t, 'devices.nameInvalid'))\n return\n }\n setDeviceBusy(deviceId)\n setDeviceMessage('')\n void props.setDeviceName!(deviceId, normalized === '' ? null : normalized).then(() => {\n setDeviceMessage(normalized === '' ? t(props.t, 'devices.nameCleared') : t(props.t, 'devices.renamed'))\n setEditingDeviceId(null)\n setDeviceNameDraft('')\n }, (error: unknown) => {\n setDeviceMessage(t(props.t, 'devices.renameFailed') + errorDetails(error))\n }).finally(() => {\n setDeviceBusy(null)\n })\n }\n\n const visibleDevices = visibleDevicesOf(report)\n // 列表只保留名称、版本和最近在线;指纹与自定义标记移入更多操作。\n // 重命名表单和删除确认仍在设备行内展开,沿用原有保存与撤销语义。\n const deviceRows = visibleDevices.length > 0\n ? h('div', { className: 'pbb-deviceList' }, visibleDevices.map((d) => {\n const editing = editingDeviceId === d.deviceId\n const busy = deviceBusy === d.deviceId\n const label = deviceLabel(d)\n const fingerprint = d.fingerprint ?? ''\n const armed = armedRevokeDeviceId === d.deviceId\n return h('div', {\n className: 'pbb-deviceRow',\n key: d.deviceId,\n 'data-armed': armed || undefined,\n 'aria-busy': busy,\n 'aria-label': t(props.t, 'devices.col.name') + ': ' + label,\n },\n h('div', { className: 'pbb-deviceMain' },\n settingsIcon('phone'),\n h('div', { className: 'pbb-deviceText' },\n h('span', { className: 'pbb-deviceName', title: label }, label),\n h('div', { className: 'pbb-deviceMeta' },\n h('span', null, d.appVersion),\n h('span', null, t(props.t, 'devices.col.lastSeen') + ' ' + formatLastSeen(d.lastSeenTs))))),\n editing\n ? h('form', {\n className: 'pbb-deviceRenameForm',\n onSubmit: (event: { preventDefault: () => void }) => {\n event.preventDefault()\n saveDeviceName(d.deviceId)\n },\n },\n h('input', {\n className: 'pbb-deviceNameInput',\n type: 'text',\n value: deviceNameDraft,\n maxLength: 64,\n autoFocus: true,\n disabled: busy,\n placeholder: t(props.t, 'devices.namePlaceholder'),\n 'aria-label': t(props.t, 'devices.nameLabel'),\n onChange: (event: { currentTarget: { value: string } }) => setDeviceNameDraft(event.currentTarget.value),\n onKeyDown: (event: { key: string; preventDefault: () => void }) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n saveDeviceName(d.deviceId)\n } else if (event.key === 'Escape') {\n event.preventDefault()\n cancelDeviceRename()\n }\n },\n }),\n h('div', { className: 'pbb-deviceRenameActions' },\n h('button', {\n type: 'submit',\n className: 'pbb-action pbb-buttonPrimary',\n disabled: busy || deviceNameDraft.length > 64,\n title: busy ? t(props.t, 'devices.nameSaving') : t(props.t, 'devices.nameSave'),\n 'aria-label': busy ? t(props.t, 'devices.nameSaving') : t(props.t, 'devices.nameSave'),\n }, busy ? t(props.t, 'devices.nameSaving') : t(props.t, 'devices.nameSave')),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: busy,\n title: t(props.t, 'devices.nameCancel'),\n 'aria-label': t(props.t, 'devices.nameCancel'),\n onClick: cancelDeviceRename,\n }, t(props.t, 'devices.nameCancel'))),\n deviceNameDraft.length > 64\n ? h('p', { className: 'pbb-diag pbb-diagBad' }, t(props.t, 'devices.nameInvalid'))\n : null)\n : null,\n armed || editing ? null : h('div', { className: 'pbb-deviceActions' },\n busy\n ? h('span', { className: 'pbb-actionBusy', role: 'status' }, t(props.t, 'devices.deleting'))\n : h(DeviceActions, {\n name: label, fingerprint, customName: d.customName,\n canRename: editingDeviceId === null && can('setDeviceName'),\n canRevoke: can('revokeDevice'), t: props.t,\n onRename: () => beginDeviceRename(d),\n onRevoke: () => {\n cancelDeviceRename()\n setArmedRevokeDeviceId(d.deviceId)\n },\n })),\n armed && !busy\n ? h('div', { className: 'pbb-deviceConfirm' },\n h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, t(props.t, 'devices.revokeConfirm', { name: label })),\n h('div', { className: 'pbb-rowAction' },\n h('button', {\n type: 'button',\n className: 'pbb-action pbb-actionDangerGhost',\n 'aria-label': t(props.t, 'devices.revokeAria', { name: label }),\n onClick: () => {\n setArmedRevokeDeviceId(null)\n revokeDevice(d.deviceId, label)\n },\n }, t(props.t, 'devices.revoke')),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n onClick: () => setArmedRevokeDeviceId(null),\n }, t(props.t, 'devices.nameCancel'))))\n : null)\n }))\n : h('p', { className: 'pbb-empty' }, t(props.t, 'devices.empty'))\n\n const switchTitle = t(props.t, 'master.title')\n const localMeta = report === null ? null : LOCAL_PHASE_META[report.local.phase]\n const remoteMeta = report === null ? null : REMOTE_PHASE_META[report.remote.phase]\n // 服务状态与点位由 view model 推导:不再用类名 includes 反推布尔。\n const service = serviceStatus({\n enabled,\n switchReady: switchReady && report !== null,\n localDot: localMeta?.dot,\n remoteDot: remoteMeta?.dot,\n })\n const serviceStatusText = t(props.t, SERVICE_STATUS_KEY[service.kind])\n const localStateText = localMeta === null ? t(props.t, 'phase.unknown') : t(props.t, CHANNEL_STATE_KEY[localMeta.label])\n const remoteStateText = remoteMeta === null ? t(props.t, 'phase.unknown') : t(props.t, CHANNEL_STATE_KEY[remoteMeta.label])\n\n // ---------- 连接诊断(P0:最近失败可观测 + 一键复制) ----------\n\n /** 一条失败事件的单行文本:时间 · 类型 · 分因,附带可选排查字段。 */\n const diagnosticLine = (failure: ReportDiagnosticFailure): string => {\n const base = t(props.t, 'diagnostics.item', {\n time: new Date(failure.ts).toLocaleString(),\n kind: t(props.t, ({\n 'upgrade-rejected': 'diagnostics.kind.upgrade', 'pair-rejected': 'diagnostics.kind.pair',\n 'auth-failed': 'diagnostics.kind.auth', 'connection-opened': 'diagnostics.kind.opened',\n 'connection-closed': 'diagnostics.kind.closed', 'connection-error': 'diagnostics.kind.error',\n identity: 'diagnostics.kind.identity', storage: 'diagnostics.kind.storage',\n } as Record<string, string>)[failure.kind] ?? 'diagnostics.kind.unknown'),\n reason: '(' + failure.kind + ' / ' + failure.reason + ')',\n })\n const extras: string[] = []\n if (failure.attemptId !== undefined) extras.push(t(props.t, 'diagnostics.attempt', { id: failure.attemptId }))\n if (failure.closeCode !== undefined) extras.push(t(props.t, 'diagnostics.closeCode', { code: failure.closeCode }))\n if (failure.durationMs !== undefined) extras.push(t(props.t, 'diagnostics.duration', { ms: failure.durationMs }))\n if (failure.source !== undefined) extras.push(t(props.t, 'diagnostics.source', { label: failure.source }))\n return extras.length === 0 ? base : base + ' · ' + extras.join(' · ')\n }\n\n /**\n * 复制诊断信息:报告里的结构化事实(版本 / 相位 / 连接数 / 最近失败)。\n * 走既有的 report 通道与 i18n;内容不含配对码、公钥、APNs token 与消息正文。\n */\n const copyDiagnostics = (): void => {\n if (report === null) return\n const enabledText = report.enabled ? t(props.t, 'diagnostics.on') : t(props.t, 'diagnostics.off')\n const failures = report.diagnostics?.recentFailures ?? []\n const lines = [\n t(props.t, 'diagnostics.reportTitle'),\n t(props.t, 'diagnostics.reportGeneratedAt') + ': ' + new Date().toLocaleString(),\n t(props.t, 'diagnostics.reportVersion') + ': v' + report.pluginVersion\n + ' (' + t(props.t, 'advanced.protocolVersion') + ' v' + String(report.protocolVersion) + ')',\n t(props.t, 'diagnostics.reportEnabled') + ': ' + enabledText,\n t(props.t, 'diagnostics.reportLocal') + ': ' + report.local.phase\n + (report.local.phase === 'online' ? ' :' + String(report.local.port) : ''),\n t(props.t, 'diagnostics.reportRemote') + ': ' + report.remote.phase,\n t(props.t, 'diagnostics.reportConnections') + ': ' + String(report.activeConnections),\n ]\n if (report.diagnostics !== undefined) {\n lines.push(t(props.t, 'diagnostics.startedAt', {\n time: new Date(report.diagnostics.startedAt).toLocaleString(),\n }))\n }\n lines.push(t(props.t, 'diagnostics.reportFailureHeader') + ':')\n if (failures.length === 0) {\n lines.push('- ' + t(props.t, 'diagnostics.reportNone'))\n } else {\n for (const failure of failures.slice(-5).reverse()) lines.push('- ' + diagnosticLine(failure))\n }\n void writeClipboard(props.t, lines.join('\\n')).then(() => {\n setDiagnosticsCopy({ message: t(props.t, 'diagnostics.copied'), failed: false })\n }, (error: unknown) => {\n setDiagnosticsCopy({\n message: t(props.t, 'diagnostics.copyFailed') + errorDetails(error),\n failed: true,\n })\n })\n }\n\n // 诊断区块放在「测试与故障排查」卡片内:与推送自测同一处,用户排查时不必\n // 在两块之间来回找。report 为 null(报告未就绪)时整块跳过。\n const diagnosticsSection = report === null ? null : h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-row' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-testTitle' }, t(props.t, 'diagnostics.title')),\n h('span', { className: 'pbb-testDescription' }, t(props.t, 'diagnostics.description'))),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n onClick: copyDiagnostics,\n 'data-testid': 'diagnosticsCopy',\n }, t(props.t, 'diagnostics.copy'))),\n diagnosticsCopy.message\n ? h('p', { className: 'pbb-diag' + (diagnosticsCopy.failed ? ' pbb-diagBad' : ''), role: 'status' }, diagnosticsCopy.message)\n : null,\n report.diagnostics === undefined\n ? h('p', { className: 'pbb-diag' }, t(props.t, 'diagnostics.staleHost'))\n : (report.diagnostics.recentFailures.length === 0\n ? h('p', { className: 'pbb-diag' }, t(props.t, 'diagnostics.empty'))\n : h('div', null,\n h('span', { className: 'pbb-label' }, t(props.t, 'diagnostics.recent')),\n report.diagnostics.recentFailures.slice(-5).reverse().map((failure, index) =>\n h('p', { className: 'pbb-diag', key: String(index) }, diagnosticLine(failure))))),\n )\n\n // ---------- 新版布局的局部构造器(仅表现层) ----------\n\n // 原生 hidden 同时移出布局、焦点顺序和无障碍树;保留挂载以保留参数草稿。\n const fold = (open: boolean, body: any): any =>\n h('div', { className: 'pbb-fold', hidden: !open }, body)\n\n /** 配对倒计时:仅在 QR 面板打开且 grant 在场时每秒刷新一次。 */\n useEffect(() => {\n if (!panel.open || pairingPanel.grant === null) return\n const timer = globalThis.setInterval(() => setNowMs(Date.now()), 1_000)\n return () => globalThis.clearInterval(timer)\n }, [panel.open, pairingPanel.grant])\n\n // 剩余时间由 grant.expiresAt 精确算出;进度条按 5 分钟窗口(qrHint 文案所载)封顶换算,仅作展示。\n const grantRemainingMs = pairingPanel.grant === null\n ? 0\n : Math.max(0, pairingPanel.grant.expiresAt - nowMs)\n const grantRemainingText = String(Math.floor(grantRemainingMs / 60_000)) + ':'\n + String(Math.floor(grantRemainingMs / 1_000) % 60).padStart(2, '0')\n const grantRemainingPct = Math.min(100, (grantRemainingMs / 300_000) * 100)\n\n const recentFailures = report?.diagnostics?.recentFailures ?? []\n const troubleGood = relayTestResult !== null\n ? relayTestResult.overall === 'ok'\n : pushTestResult !== null\n ? pushTestResult.overall === 'sent'\n : false\n const troubleBad = relayTestResult !== null\n ? relayTestResult.overall !== 'ok'\n : pushTestResult !== null\n ? pushTestResult.overall !== 'sent'\n : recentFailures.length > 0\n const troubleConclusion = relayTestResult !== null\n ? (relayTestResult.overall === 'ok' ? t(props.t, 'push.relayOk') : t(props.t, 'push.relayBad'))\n : pushTestResult !== null\n ? (pushTestResult.overall === 'sent' ? t(props.t, 'push.pushSent') : t(props.t, 'push.pushFailed'))\n : recentFailures.length > 0\n ? t(props.t, 'diagnostics.historyCount', { count: recentFailures.length })\n : ''\n\n // 默认状态与已确认画布一致;配对面板只在用户点击添加后生成一次性凭据。\n const pairingSection = h('div', { id: pairingId, hidden: !pairingOpen },\n !pairingOpen || report === null ? null : h('div', { className: 'pbb-pairingPanel' },\n h('div', { className: 'pbb-pairingHeader' },\n h('h3', { className: 'pbb-cardTitle' }, t(props.t, 'pair.qrPanelTitle')),\n !panel.open && pairingTarget !== null\n ? h('button', {\n type: 'button', className: 'pbb-action',\n disabled: panel.busy || !report.pairingReady,\n onClick: () => showPairingQR(pairingTarget),\n }, t(props.t, 'pair.qrShow'))\n : null),\n h('div', { className: 'pbb-pairingBody' },\n pairingTarget === null\n ? h('p', { className: 'pbb-diag' }, enabled ? t(props.t, 'pair.noAddressHelp') : t(props.t, 'pair.disabledHelp'))\n : null,\n pairingTargets.length < 2 ? null : h('div', { className: 'pbb-targetList' },\n pairingTargets.map((target) => h('button', {\n type: 'button',\n key: target.host,\n className: 'pbb-targetButton' + (target.host === pairingTarget?.host ? ' pbb-targetSelected' : ''),\n // A grant is single-use and cannot be recalled, so a switch clicked\n // while one is already being issued would spend a second code that\n // nothing ever displays. Wait for the in-flight issue instead.\n disabled: panel.busy,\n onClick: () => {\n setSelectedPairingHost(target.host)\n // Switching between LAN and public keeps the panel open by\n // re-issuing a grant for the newly selected address, so both\n // networks are one tap away instead of a collapse and re-open.\n if (panel.open) showPairingQR(target)\n else hidePairingQR()\n },\n }, (target.kind === 'public' ? t(props.t, 'pair.kind.public') : t(props.t, 'pair.kind.lan')) + ' · ' + target.host)),\n ),\n panel.message ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, panel.message) : null,\n panel.notice ? h('p', { className: 'pbb-diag', role: 'status' }, panel.notice) : null,\n panel.failed && pairingTarget !== null\n ? h('div', { className: 'pbb-rowAction' },\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: panel.busy || (report !== null && !report.pairingReady),\n onClick: () => showPairingQR(pairingTarget),\n }, t(props.t, 'pair.qrRetry')))\n : null,\n panel.open && !panel.failed ? h('div', { className: 'pbb-qrPanel' },\n h('div', null,\n panel.qrDataURL === null ? h('p', { className: 'pbb-diag' }, t(props.t, 'pair.qrGenerating')) : h('img', {\n className: 'pbb-qrImage',\n src: panel.qrDataURL,\n alt: t(props.t, 'pair.qrAlt'),\n }),\n pairingPanel.grant === null ? null : h('div', { className: 'pbb-countdown' },\n h('div', { className: 'pbb-countdownBar' },\n h('i', { style: { transform: 'scaleX(' + String(grantRemainingPct / 100) + ')' } })),\n h('span', { className: 'pbb-countdownText' }, grantRemainingText)),\n ),\n h('div', { className: 'pbb-pairInfo' },\n // The only credentials row on this page: host, single-use code and\n // (for LAN) the certificate pin travel together in one string, so the\n // phone needs one paste and nothing is shown twice.\n panel.link === null ? null : h('div', { className: 'pbb-pairCodeBlock' },\n h('span', { className: 'pbb-pairCodeLabel' }, t(props.t, 'pair.infoLabel')),\n h('div', { className: 'pbb-pairCodeRow' },\n h('code', { className: 'pbb-pairCode' }, panel.link),\n h('button', {\n type: 'button',\n className: 'pbb-action pbb-buttonPrimary',\n onClick: copyPairingInfo,\n 'data-testid': 'pairingInfoCopy',\n }, t(props.t, 'panel.tokenAction.copy')))),\n h('p', { className: 'pbb-qrHint' },\n t(props.t, 'pair.qrHint', {\n kind: panel.target?.kind === 'public' ? t(props.t, 'pair.kind.public') : t(props.t, 'pair.kind.lan'),\n }),\n ),\n ),\n ) : null,\n ),\n ))\n\n return h('div', { className: 'pbb-section' },\n h('header', { className: 'pbb-pageHeader' },\n h('div', null,\n h('h2', { className: 'pbb-title' }, 'DeepPilot'),\n h('p', { className: 'pbb-intro' }, t(props.t, 'meta.intro'))),\n h('button', {\n type: 'button', className: 'pbb-refresh', disabled: !can('refresh'),\n onClick: () => props.refresh?.(),\n }, settingsIcon('refresh', 14), t(props.t, 'meta.refresh'))),\n h('section', { className: 'pbb-card pbb-connections', 'aria-label': t(props.t, 'connection.title') },\n h('div', { className: 'pbb-cardBody' },\n h('div', { className: 'pbb-masterRow' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-controlTitle' }, switchTitle),\n h('div', { className: 'pbb-serviceSummary' },\n h('span', { className: 'pbb-serviceState' + (service.kind === 'ready' ? ' pbb-ok' : service.kind === 'attention' ? ' pbb-bad' : '') },\n settingsIcon(service.kind === 'ready' ? 'ready' : service.kind === 'attention' ? 'attention' : 'info', 13)),\n h('span', null, serviceStatusText),\n h('span', { className: 'pbb-metaDivider', 'aria-hidden': true }),\n h('span', null, t(props.t, 'panel.activeConnections') + ' '\n + (report === null ? '—' : String(report.activeConnections))))),\n h(Switch, {\n checked: enabled,\n label: switchTitle,\n disabled: !switchReady,\n onChange: (next: boolean) => {\n if (can('setEnabled')) props.setDeepPilotEnabled!(next)\n },\n }),\n ),\n h('div', { className: 'pbb-channel' },\n h('div', { className: 'pbb-row pbb-channelRow' },\n settingsIcon('wifi'),\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-controlTitle' },\n t(props.t, 'local.title')),\n h('div', { className: 'pbb-channelState' }, h('span', { className: localMeta?.label === 'online' ? 'pbb-ok' : localMeta?.label === 'error' ? 'pbb-bad' : undefined }, localStateText))),\n h(Switch, {\n checked: localEnabled,\n label: t(props.t, 'local.title'),\n disabled: !localSwitchReady,\n onChange: (next: boolean) => {\n if (can('setLocalEnabled')) props.setDeepPilotLocalEnabled!(next)\n },\n }),\n h('button', {\n type: 'button', className: 'pbb-iconButton pbb-expand',\n 'aria-label': t(props.t, 'local.options'),\n 'aria-expanded': localOptionsOpen, 'aria-controls': localOptionsId,\n onClick: () => setLocalOptionsOpen(!localOptionsOpen),\n }, h('span', { className: 'pbb-chev' }, ChevronIcon())),\n ),\n report !== null && report.local.message && report.local.phase === 'error'\n ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, t(props.t, 'local.errorDetails', { message: report.local.message }))\n : null,\n report !== null && report.local.tlsIdentityRegenerated === true\n ? h('p', { className: 'pbb-diag pbb-diagBad' }, t(props.t, 'local.tlsRegenerated'))\n : null,\n fold(localOptionsOpen, h('div', { className: 'pbb-channelBody', id: localOptionsId },\n report !== null && report.local.phase === 'online'\n ? h('p', { className: 'pbb-diag pbb-endpoint' }, report.local.endpoints.join(' · ')) : null,\n h('div', { className: 'pbb-limitRow' },\n h('div', { className: 'pbb-controlText' },\n h('label', { className: 'pbb-controlTitle', htmlFor: 'deeppilot-local-port' }, t(props.t, 'local.portTitle')),\n h('span', { className: 'pbb-controlDescription' }, t(props.t, 'local.portDescription')),\n !localPortView.valid\n ? h('p', { className: 'pbb-diag pbb-diagBad' }, t(props.t, 'local.portInvalid'))\n : localPortDraft.message\n ? h('p', {\n className: 'pbb-diag' + (localPortDraft.failed ? ' pbb-diagBad' : ''),\n }, localPortDraft.message)\n : null,\n ),\n h('div', { className: 'pbb-limitControl' },\n h('input', {\n id: 'deeppilot-local-port',\n className: 'pbb-numberInput',\n type: 'number',\n min: LOCAL_PORT_RANGE.min,\n max: LOCAL_PORT_RANGE.max,\n step: 1,\n inputMode: 'numeric',\n value: localPortDraft.draft,\n disabled: !localPortReady,\n 'aria-label': t(props.t, 'local.portTitle'),\n onChange: (event: { currentTarget: { value: string } }) => dispatchLocalPortDraft({ type: 'edit', draft: event.currentTarget.value }),\n onKeyDown: (event: { key: string; preventDefault: () => void }) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n applyLocalPort()\n }\n },\n }),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: !localPortReady || !localPortView.valid || localPortView.unchanged,\n onClick: applyLocalPort,\n }, t(props.t, 'remote.limitApply')),\n ),\n ),\n report !== null && report.local.phase === 'online' && report.local.tlsFingerprint\n ? h('div', { className: 'pbb-limitRow' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-controlTitle' }, t(props.t, 'local.tlsFingerprint')),\n h('code', { className: 'pbb-token' }, report.local.tlsFingerprint)))\n : null,\n )),\n ),\n h('div', { className: 'pbb-channel' },\n h('div', { className: 'pbb-row pbb-channelRow' },\n settingsIcon('globe'),\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-controlTitle' },\n t(props.t, 'remote.title')),\n h('div', { className: 'pbb-channelState' }, h('span', { className: remoteMeta?.label === 'online' ? 'pbb-ok' : (remoteMeta?.label === 'error' || remoteMeta?.label === 'unavailable') ? 'pbb-bad' : undefined }, remoteStateText), h('span', { className: 'pbb-metaDivider', 'aria-hidden': true }), h('span', null, 'Tailscale Funnel'))),\n h(Switch, {\n checked: remoteEnabled,\n label: t(props.t, 'remote.title'),\n disabled: !remoteSwitchReady,\n onChange: (next: boolean) => {\n if (can('setRemoteEnabled')) props.setDeepPilotRemoteEnabled!(next)\n },\n }),\n h('button', {\n type: 'button', className: 'pbb-iconButton pbb-expand',\n 'aria-label': t(props.t, 'remote.options'),\n 'aria-expanded': remoteOptionsOpen, 'aria-controls': remoteOptionsId,\n onClick: () => setRemoteOptionsOpen(!remoteOptionsOpen),\n }, h('span', { className: 'pbb-chev' }, ChevronIcon())),\n ),\n report !== null && report.remote.phase === 'login_required'\n && typeof report.remote.authURL === 'string' && report.remote.authURL.startsWith('https://')\n ? h('div', { className: 'pbb-rowAction' },\n h('a', { className: 'pbb-action pbb-buttonPrimary', href: report.remote.authURL, target: '_blank', rel: 'noreferrer' }, t(props.t, 'remote.openAuth')))\n : null,\n report !== null && report.remote.message && (report.remote.phase === 'error' || report.remote.phase === 'unavailable')\n ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, t(props.t, 'remote.errorDetails', { message: report.remote.message }))\n : null,\n fold(remoteOptionsOpen, h('div', { className: 'pbb-channelBody', id: remoteOptionsId },\n report !== null && report.remote.phase === 'online'\n ? h('p', { className: 'pbb-diag pbb-endpoint' }, report.remote.publicURL) : null,\n h('div', { className: 'pbb-limitRow' },\n h('div', { className: 'pbb-controlText' },\n h('label', { className: 'pbb-controlTitle', htmlFor: 'deeppilot-funnel-source-limit' }, t(props.t, 'remote.limitTitle')),\n h('span', { className: 'pbb-controlDescription' }, t(props.t, 'remote.limitDescription')),\n !remoteLimitView.valid\n ? h('p', { className: 'pbb-diag pbb-diagBad' }, t(props.t, 'remote.limitInvalid'))\n : remoteLimitDraft.message\n ? h('p', {\n className: 'pbb-diag' + (remoteLimitDraft.failed ? ' pbb-diagBad' : ''),\n }, remoteLimitDraft.message)\n : null,\n ),\n h('div', { className: 'pbb-limitControl' },\n h('input', {\n id: 'deeppilot-funnel-source-limit',\n className: 'pbb-numberInput',\n type: 'number',\n min: 1,\n max: REMOTE_LIMIT_RANGE.max,\n step: 1,\n inputMode: 'numeric',\n value: remoteLimitDraft.draft,\n disabled: !remoteConnectionLimitReady,\n 'aria-label': t(props.t, 'remote.limitTitle'),\n onChange: (event: { currentTarget: { value: string } }) => dispatchRemoteLimitDraft({ type: 'edit', draft: event.currentTarget.value }),\n onKeyDown: (event: { key: string; preventDefault: () => void }) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n applyRemoteLimit()\n }\n },\n }),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: !remoteConnectionLimitReady || !remoteLimitView.valid || remoteLimitView.unchanged,\n onClick: applyRemoteLimit,\n }, t(props.t, 'remote.limitApply')),\n ),\n ),\n h('details', { className: 'pbb-helpDisclosure' },\n h('summary', null, h('span', { className: 'pbb-chev' }, ChevronIcon()), t(props.t, 'help.remoteTitle')),\n h('div', { className: 'pbb-helpBody' },\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.recommended')),\n h('ol', { className: 'pbb-helpList' },\n h('li', null, t(props.t, 'help.step1')),\n h('li', null, t(props.t, 'help.step2')),\n h('li', null, t(props.t, 'help.step3')),\n h('li', null, t(props.t, 'help.step4')),\n ),\n h('p', { className: 'pbb-helpText' }, t(props.t, 'help.funnelHint')),\n ),\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.httpsTitle')),\n h('ol', { className: 'pbb-helpList' },\n h('li', null, t(props.t, 'help.httpsStep1')),\n h('li', null, t(props.t, 'help.httpsStep2')),\n h('li', null, t(props.t, 'help.httpsStep3')),\n ),\n h('p', { className: 'pbb-helpText' }, t(props.t, 'help.httpsHint')),\n ),\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.allowTitle')),\n h('p', { className: 'pbb-helpText' }, t(props.t, 'help.allowBody')),\n h('code', { className: 'pbb-helpCode' }, '\"nodeAttrs\": [\\n {\\n \"target\": [\"autogroup:member\"],\\n \"attr\": [\"funnel\"],\\n },\\n],'),\n h('p', { className: 'pbb-helpText' }, t(props.t, 'help.allowHint')),\n ),\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.faqTitle')),\n h('ul', { className: 'pbb-helpList' },\n h('li', null, t(props.t, 'help.faq1')),\n h('li', null, t(props.t, 'help.faq2')),\n h('li', null, t(props.t, 'help.faq3')),\n h('li', null, t(props.t, 'help.faq4')),\n ),\n ),\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.securityTitle')),\n h('ul', { className: 'pbb-helpList' },\n h('li', null, t(props.t, 'help.security1')),\n h('li', null, t(props.t, 'help.security2')),\n h('li', null, t(props.t, 'help.security3')),\n h('li', null, t(props.t, 'help.security4')),\n h('li', null, t(props.t, 'help.security5')),\n ),\n h('p', { className: 'pbb-helpText' },\n t(props.t, 'help.docsPrefix'),\n h('a', { className: 'pbb-helpLink', href: 'https://tailscale.com/docs/features/tailscale-funnel', target: '_blank', rel: 'noreferrer' }, t(props.t, 'help.funnelDocs'))),\n ),\n )),\n )),\n ),\n ),\n ),\n h('section', { className: 'pbb-devicesSection', 'aria-label': t(props.t, 'devices.title') },\n h('div', { className: 'pbb-devicesHeader' },\n h('h3', { className: 'pbb-cardTitle' }, t(props.t, 'devices.title')),\n h('span', { className: 'pbb-deviceCount' }, t(props.t, 'devices.count', { count: visibleDevices.length })),\n h('div', { className: 'pbb-addAction' }, h(Button, {\n variant: 'outline', size: 'sm', icon: settingsIcon('plus', 16),\n disabled: panel.busy || report === null || !report.pairingReady || !can('beginPairing'),\n 'aria-expanded': pairingOpen, 'aria-controls': pairingId,\n onClick: () => {\n if (pairingOpen) { hidePairingQR(); setPairingOpen(false); return }\n setPairingOpen(true)\n if (pairingTarget !== null && report?.pairingReady) showPairingQR(pairingTarget)\n },\n }, t(props.t, pairingOpen ? 'pair.close' : 'pair.add')))),\n pairingSection,\n h('div', { className: 'pbb-card pbb-devicesCard' },\n deviceMessage ? h('p', {\n className: 'pbb-diag pbb-deviceMessage' + (deviceMessage.startsWith(t(props.t, 'devices.renameFailed')) || deviceMessage.startsWith(t(props.t, 'devices.revokeFailed')) ? ' pbb-diagBad' : ''),\n role: 'status',\n }, deviceMessage) : null,\n deviceRows)),\n h('section', { className: 'pbb-card pbb-tools', 'aria-label': t(props.t, 'tools.title') },\n h('div', { className: 'pbb-toolSection' },\n h('button', {\n type: 'button',\n className: 'pbb-cardHead',\n 'aria-expanded': troubleshootingOpen, 'aria-controls': troubleshootingId,\n onClick: () => setTroubleshootingOpen(!troubleshootingOpen),\n },\n settingsIcon('activity', 17),\n h('span', { className: 'pbb-cardTitle' }, t(props.t, 'troubleshooting.summary')),\n h('span', { className: 'pbb-toolMeta' + (troubleGood ? ' pbb-ok' : troubleBad && relayTestResult !== null ? ' pbb-bad' : '') }, troubleConclusion),\n h('span', { className: 'pbb-chev' }, ChevronIcon())),\n fold(troubleshootingOpen, h('div', { className: 'pbb-cardBody', id: troubleshootingId },\n h('div', { className: 'pbb-testGrid' },\n h('div', { className: 'pbb-testItem' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-testTitle' }, t(props.t, 'push.relayTitle')),\n h('span', { className: 'pbb-testDescription' }, t(props.t, 'push.relayDefault'))),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: relayTestBusy,\n onClick: runRelayTest,\n }, relayTestBusy ? t(props.t, 'push.relayTesting') : t(props.t, 'push.testRelay'))),\n h('div', { className: 'pbb-testItem' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-testTitle' }, t(props.t, 'push.testPush')),\n h('span', { className: 'pbb-testDescription' }, t(props.t, 'push.pushDefault'))),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: pushTestBusy,\n onClick: sendPushTest,\n }, pushTestBusy ? t(props.t, 'push.pushSending') : t(props.t, 'push.testPush'))),\n h('div', { className: 'pbb-testItem' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-testTitle' }, t(props.t, 'troubleshooting.debugTitle')),\n h('span', { className: 'pbb-testDescription' }, t(props.t, 'troubleshooting.debugDescription'))),\n h(Switch, {\n checked: debugEnabled,\n label: t(props.t, 'troubleshooting.debugTitle'),\n disabled: !debugSwitchReady,\n onChange: (next: boolean) => {\n if (can('setDebug')) props.setDeepPilotDebug!(next)\n },\n }))),\n relayTestError ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, relayTestError) : null,\n relayTestResult === null\n ? null\n : h('div', { className: 'pbb-helpBody' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, relayTestResult.url || t(props.t, 'push.relayUrlEmpty')),\n h('code', { className: 'pbb-token ' + (relayTestResult.overall === 'ok' ? 'pbb-ok' : 'pbb-bad') },\n relayTestResult.overall === 'ok' ? t(props.t, 'push.relayOk') : t(props.t, 'push.relayBad')),\n ),\n relayTestResult.steps.map((step: any, index: number) =>\n resultRow(step.ok, (step.id === 'health' ? t(props.t, 'push.relayStep.health') : t(props.t, 'push.relayStep.enroll'))\n + (step.latencyMs !== undefined ? ` (${String(step.latencyMs)}ms)` : '')\n + '(' + step.message + ')', String(index))),\n ),\n pushTestError ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, pushTestError) : null,\n pushTestResult === null\n ? null\n : h('div', { className: 'pbb-helpBody' },\n h('div', { className: 'pbb-row' },\n h('code', { className: 'pbb-token ' + (pushTestResult.overall === 'sent' ? 'pbb-ok' : pushTestResult.overall === 'failed' ? 'pbb-bad' : '') },\n pushTestResult.overall === 'sent' ? t(props.t, 'push.pushSent')\n : pushTestResult.overall === 'failed' ? t(props.t, 'push.pushFailed')\n : pushTestResult.overall === 'no-targets' ? t(props.t, 'push.pushNoTargets') : t(props.t, 'push.pushNotEnabled'))),\n pushTestResult.message ? h('p', { className: 'pbb-diag' }, t(props.t, 'push.resultDetail', { message: pushTestResult.message })) : null,\n pushTestResult.results.map((r: any, index: number) =>\n resultRow(r.outcome === 'sent', r.name + '('\n + t(props.t, r.environment === 'production' ? 'push.environment.production' : r.environment === 'development' ? 'push.environment.development' : 'push.environment.other', { environment: r.environment }) + ') · '\n + t(props.t, r.outcome === 'sent' ? 'push.outcome.sent' : r.outcome === 'invalid-token' ? 'push.outcome.invalid' : r.outcome === 'failed' ? 'push.outcome.failed' : 'push.outcome.other', { outcome: r.outcome }) + (r.reason ? '(' + r.reason + ')' : '')\n + (r.tokenFingerprint ? ' token:' + r.tokenFingerprint + '…' : ''), String(index))),\n ),\n diagnosticsSection,\n )),\n ),\n report === null ? null : h('div', { className: 'pbb-toolSection' },\n h('button', {\n type: 'button',\n className: 'pbb-cardHead',\n 'aria-expanded': systemOpen, 'aria-controls': systemId,\n onClick: () => setSystemOpen(!systemOpen),\n },\n settingsIcon('info', 17),\n h('span', { className: 'pbb-cardTitle' }, t(props.t, 'system.summary')),\n h('span', { className: 'pbb-toolMeta' + (report.updateAvailable === true ? ' pbb-ok' : '') },\n 'v' + report.pluginVersion + (report.updateAvailable === true ? ' · ' + t(props.t, 'update.badge') : '')),\n h('span', { className: 'pbb-chev' }, ChevronIcon())),\n fold(systemOpen, h('div', { className: 'pbb-cardBody', id: systemId },\n h('div', { className: 'pbb-sectionIntro' },\n h('h3', { className: 'pbb-cardTitle' }, t(props.t, 'system.title'))),\n h('div', { className: 'pbb-runtimeList' },\n h('div', { className: 'pbb-runtimeRow' },\n h('span', { className: 'pbb-label' }, 'DeepPilot'),\n h('span', { className: 'pbb-value' }, 'v' + report.pluginVersion)),\n // 内嵌 helper 自报的 Tailscale 版本:远程连接从未启动(或 helper 缺失)\n // 时 Host 不带该字段,这里显示「未获取」而不是从 go.mod 猜一个值。\n h('div', { className: 'pbb-runtimeRow' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.tailscaleVersion')),\n h('span', { className: 'pbb-value' },\n report.remote.tailscaleVersion ?? t(props.t, 'advanced.tailscaleVersionUnknown'))),\n h('div', { className: 'pbb-runtimeRow' },\n h('span', { className: 'pbb-label' }, t(props.t, 'panel.identity')),\n h('span', { className: 'pbb-value' }, t(props.t, report.pairingReady ? 'panel.identityReady' : 'panel.identityNotReady'))),\n advancedRows,\n report.updateAvailable === true\n ? h('a', {\n className: 'pbb-updateRow',\n href: typeof report.releaseUrl === 'string' && /^https:\\/\\//.test(report.releaseUrl)\n ? report.releaseUrl\n : 'https://github.com/Mars-Sea/dsh-deeppilot/releases',\n target: '_blank',\n rel: 'noreferrer',\n },\n h('span', null, t(props.t, 'update.badge')),\n h('span', { className: 'pbb-chev' }, ChevronIcon()))\n : null))),\n )),\n diag.length > 0 ? h('details', {\n className: 'pbb-card pbb-disclosure pbb-diagnostics',\n open: failed,\n },\n // 与其它可折叠卡同一个 SVG 箭头:收起朝右,展开转 90° 朝下。\n h('summary', null,\n h('span', { className: 'pbb-chev' }, ChevronIcon()),\n h('span', { className: 'pbb-disclosureTitle' }, t(props.t, 'diag.summary'))),\n h('div', { className: 'pbb-disclosureBody' },\n h('p', { className: 'pbb-diag' + (failed ? ' pbb-diagBad' : '') },\n t(props.t, 'diag.prefix') + diag.join(' | ')))) : null,\n )\n}\n","/**\n * 设置页左侧导航里 DeepPilot 一行的图标。\n *\n * DSH 0.2.2 的设置壳为每个 `settings.section` 渲染\n * `renderSlot('settings.section.icon', { size, active }, { only: id, fallback })`:\n * 有同 id 的图标贡献就用它,否则画默认齿轮。壳负责按钮、文字和装饰性外框\n * (外框已 `aria-hidden`),图标只需按 `size` 画一个随文字颜色变化的线性 SVG。\n *\n * 不用 `icon.svg`:那是插件管理页的彩色品牌图(渐变填充、白底),放进导航行\n * 会和内置单色线性图标格格不入,也违反「图标统一用线性单色 SVG」的要求。\n * 这里画一部手机(DeepPilot 的职责是把手机接到这台电脑的 DSH),描边沿用\n * 设置页其他图标的 16×16 视图框和 1.5 线宽。\n */\nimport { createElement as h } from 'react'\n\n/** 壳传入的图标属性(`SettingsSectionIconOwnerProps`)。`active` 由壳的样式\n * 体现(文字颜色经 currentColor 传到描边),图标本身不需要分支。 */\nexport interface NavIconProps {\n size?: number\n active?: boolean\n}\n\n/** 导航行默认边长;壳当前固定传 16。 */\nconst DEFAULT_NAV_ICON_SIZE = 16\n\nexport const DeepPilotNavIcon = ({ size }: NavIconProps): any => {\n const edge = typeof size === 'number' && size > 0 ? size : DEFAULT_NAV_ICON_SIZE\n return h('svg', {\n viewBox: '0 0 16 16',\n width: edge,\n height: edge,\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 1.5,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n 'aria-hidden': true,\n focusable: 'false',\n },\n // 机身\n h('rect', { x: 4.25, y: 1.75, width: 7.5, height: 12.5, rx: 1.75 }),\n // 底部指示条\n h('path', { d: 'M7 11.75h2' }),\n )\n}\n","/**\n * Bind the rc.2 profile config form for the browser half of the plugin.\n * The adapter preserves the settings page's snapshot and rejected-write\n * behavior while the form reads and writes this plugin's profile entry.\n *\n * Structural types only (no value imports): the client bundle's runtime\n * require allowlist is react + @deepseek-ai/cordis.\n */\n\n/** Section fields the settings page reads; other config keys pass through. */\nexport interface SettingsSectionValue {\n enabled?: boolean\n local?: { enabled?: boolean; port?: number; [key: string]: unknown }\n remote?: { enabled?: boolean; maxConnectionsPerSource?: number; [key: string]: unknown }\n diagnostics?: { debug?: boolean; [key: string]: unknown }\n [key: string]: unknown\n}\n\nexport interface ScopeSnapshot {\n status: 'loading' | 'ready' | 'unavailable'\n value?: SettingsSectionValue\n writable?: boolean\n}\n\n/** The settings page's local snapshot and write contract. */\nexport interface SettingsScopeLike {\n getSnapshot(): ScopeSnapshot\n subscribe(listener: () => void): () => void\n set(field: string, value: unknown): Promise<void>\n unset(field: string): Promise<void>\n}\n\n/** 0.1.7 ConfigFormController surface used here (structural subset). */\ninterface ConfigFormLike {\n getSnapshot(): ScopeSnapshot\n subscribe(listener: () => void): () => void\n set(field: string, value: unknown): Promise<boolean>\n unset(field: string): Promise<boolean>\n}\n\n/** 0.1.7 `ctx.configForms` service face (structural subset). */\nexport interface ConfigFormsLike {\n get?(entryId: string): ConfigFormLike\n}\n\ninterface SettingsScopeProvider {\n /**\n * Cordis service lookup. Real contexts carry this and MUST be read through\n * it: a context proxy throws `cannot get property \"<name>\" without inject`\n * when an undeclared service property is read. The form is resolved through\n * `get` because it may be provided after this entry applies.\n */\n get(name: string): unknown\n}\n\n/**\n * Deep-unwrap live-update references in a snapshot section.\n *\n * Volatile fields can arrive as `{ get() }` references. The settings page\n * compares plain values, so unwrap them at this boundary.\n */\nfunction plainSection(value: SettingsSectionValue | undefined): SettingsSectionValue | undefined {\n if (value === null || typeof value !== 'object') return value\n if (typeof (value as { get?: unknown }).get === 'function') {\n return plainSection((value as { get: () => SettingsSectionValue }).get())\n }\n const plain: Record<string, unknown> = {}\n for (const [key, item] of Object.entries(value)) {\n plain[key] = item !== null && typeof item === 'object' ? plainSection(item as SettingsSectionValue) : item\n }\n return plain as SettingsSectionValue\n}\n\n/**\n * Adapt one config form to the settings page's local contract.\n *\n * The form resolves writes as `Promise<boolean>` (false = the Host rejected or\n * could not recover the write) where the scope face signals failure by\n * rejecting — the page's optimistic-write rollback only runs on rejection, so\n * a `false` must be translated into one.\n *\n * @param forms - the 0.1.7 configForms service, if the host provides it.\n * @param entryId - profile entry id.\n * @returns the adapted scope, or undefined when the service cannot resolve it.\n */\nexport function adaptConfigForm(forms: ConfigFormsLike | undefined, entryId: string): SettingsScopeLike | undefined {\n const form = forms?.get?.(entryId)\n if (form === undefined) return undefined\n const accept = async (pending: Promise<boolean>): Promise<void> => {\n if (!(await pending)) throw new Error('host rejected the settings write')\n }\n return {\n getSnapshot: () => {\n const snapshot = form.getSnapshot()\n return {\n status: snapshot.status,\n value: plainSection(snapshot.value),\n writable: snapshot.writable,\n }\n },\n subscribe: (listener) => form.subscribe(listener),\n set: (field, value) => accept(form.set(field, value)),\n unset: (field) => accept(form.unset(field)),\n }\n}\n\n/**\n * Bind the rc.2 form if its service is already provisioned. Callers that\n * apply first retry inside `ctx.inject(['configForms'], …)`.\n */\nexport function bindConfigForm(ctx: SettingsScopeProvider): SettingsScopeLike | undefined {\n return adaptConfigForm(ctx.get('configForms') as ConfigFormsLike | undefined, 'deeppilot')\n}\n","/**\n * Browser half of the dsh-deeppilot bundle.\n *\n * Registers a \"DeepPilot\" settings page following the exact structure of the\n * working settings pages in the harness: a controller + local snapshot store\n * surfaced to the slot component as a `use` hook, with\n * the report fetched Host-side through the deeppilot/report Typert Remote.\n * The master switch (enabled) is read/written through the shared settings\n * profile config form (`ctx.configForms.get('deeppilot')`), the same entry the\n * Host half reads.\n *\n * The slot `inject` MUST be a thunk returning the inject face — the renderer\n * calls `entry.inject(...)`; passing a plain object used to throw\n * \"inject is not a function\" inside the slot boundary and silently blank the\n * whole section. The component renders a visible diagnostic line on any\n * failure mode so a broken setup is never a silent blank panel.\n */\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { DeepPilotReport, PairingGrantSnapshot } from '../report-wire.ts'\nimport { createSnapshotStore } from './snapshot-store.ts'\nimport { mountReportRemote } from './report-mount.ts'\nimport type { ClientRemoteLike, ReportRemote } from './report-mount.ts'\nimport { registerLocale as registerDeepPilotLocale, t } from './i18n.ts'\nimport type { PushTestResult, RelayTestResult } from '../report-wire.ts'\nimport { injectCss } from './styles.ts'\nimport { DeepPilotSettingsPage } from './settings-page.ts'\nimport { DeepPilotNavIcon } from './nav-icon.ts'\nimport { DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE, normalizeFunnelConnectionLimit } from '../funnel-policy.ts'\nimport { DEFAULT_LOCAL_PORT, normalizeLocalPort } from '../local-policy.ts'\nimport {\n bindConfigForm,\n type ConfigFormsLike,\n type SettingsScopeLike,\n} from './config-form.ts'\n\nexport { DeepPilotSettingsPage } from './settings-page.ts'\n\ntype AnyCtx = Context & {\n locale?: {\n register: (key: string, table: unknown) => () => void\n bind: (key: string) => (k: string, vars?: Readonly<Record<string, unknown>>) => string\n getSnapshot?: () => { active: string; revision: number }\n }\n remote?: ClientRemoteLike\n slots?: {\n inject: (name: string, cb: () => unknown) => unknown\n register: (entry: unknown, component: unknown) => unknown\n }\n configForms?: ConfigFormsLike\n}\n\n/** Controller state surfaced to the page through the snapshot store. */\nexport interface PageState {\n status: 'loading' | 'ready' | 'error'\n report: DeepPilotReport | null\n /** Visible diagnostic message for the error state. */\n message: string\n}\n\n/** Master-switch state surfaced to the page through its own snapshot store. */\nexport interface EnabledState {\n status: 'loading' | 'ready' | 'unavailable'\n enabled: boolean\n}\n\nexport interface RemoteEnabledState {\n status: 'loading' | 'ready' | 'unavailable'\n enabled: boolean\n}\n\nexport interface LocalEnabledState {\n status: 'loading' | 'ready' | 'unavailable'\n enabled: boolean\n}\n\n/** Diagnostics toggle state (\"测试与故障排查\" panel), read from `diagnostics.debug`. */\nexport interface DebugState {\n status: 'loading' | 'ready' | 'unavailable'\n enabled: boolean\n}\n\nexport interface LocalPortState {\n status: 'loading' | 'ready' | 'unavailable'\n value: number\n}\n\nexport interface RemoteConnectionLimitState {\n status: 'loading' | 'ready' | 'unavailable'\n value: number\n}\n\n/** Bound translation function shape used everywhere in this file. The\n * t() helper from i18n.ts has the same signature; we name it T here so\n * consumers in the page can pass it through props without depending on\n * the i18n module directly. */\ntype T = (key: string, vars?: Readonly<Record<string, unknown>>) => string\n\n/** Polls the report remote and owns the page state transitions. */\nclass ReportController {\n private listeners = new Set<() => void>()\n private snap: PageState = { status: 'loading', report: null, message: '' }\n\n constructor(\n private readonly fetchReport: () => Promise<DeepPilotReport | null>,\n private readonly t: T,\n ) {}\n\n state(): PageState {\n return this.snap\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n dispose(): void {\n this.listeners.clear()\n }\n\n async refresh(): Promise<void> {\n try {\n const report = await this.fetchReport()\n this.snap = report !== null\n ? { status: 'ready', report, message: '' }\n : { status: 'error', report: null, message: this.t('diag.mountFailed') }\n } catch (error) {\n this.snap = { status: 'error', report: null, message: error instanceof Error ? error.message : String(error) }\n }\n this.emit()\n }\n\n private emit(): void {\n for (const listener of [...this.listeners]) {\n try { listener() } catch { /* listener errors stay isolated */ }\n }\n }\n}\n\n/**\n * Services this client entry cannot start without.\n *\n * `configForms` is provided by the settings-page fiber, which may activate\n * after this entry. It is attached through an optional injection below so\n * the entry can activate before the settings page does.\n */\nexport const inject: readonly string[] = ['slots', 'locale', 'remote']\n\nexport function apply(ctx: Context): void {\n if (typeof document !== 'undefined') injectCss()\n const anyCtx = ctx as AnyCtx\n\n // Hand the locale face our full zh/en dictionary. The page is reachable\n // without a locale face: t() falls back to a built-in copy of the same\n // table so missing host injection never blanks the UI.\n ctx.effect(\n () => registerDeepPilotLocale(ctx),\n 'dsh-deeppilot: locale dictionaries',\n )\n\n let namespace: ReportRemote | undefined\n let mountError: string | undefined\n\n const fetchReport = async (): Promise<DeepPilotReport | null> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n const result = await namespace.report()\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'diag.callFailed'))\n return result.value\n }\n\n const tPage: T = (key, vars) => t(ctx, key, vars)\n const controller = new ReportController(fetchReport, tPage)\n ctx.effect(() => () => controller.dispose(), 'dsh-deeppilot: report controller')\n const store = createSnapshotStore<PageState>(controller.state())\n controller.subscribe(() => store.set(controller.state()))\n\n ctx.effect(() => {\n let cancelled = false\n let unmount: (() => Promise<void>) | undefined\n if (anyCtx.remote === undefined) {\n mountError = t(ctx, 'diag.remoteUnavailable')\n void controller.refresh()\n return () => {}\n }\n void mountReportRemote(\n anyCtx.remote,\n () => ctx.get('remote.deeppilot') as ReportRemote | undefined,\n )\n .then((mounted) => {\n if (cancelled) { void mounted.dispose(); return }\n namespace = mounted.namespace\n unmount = mounted.dispose\n mountError = undefined\n void controller.refresh()\n }, (error: unknown) => {\n mountError = error instanceof Error ? error.message : String(error)\n void controller.refresh()\n })\n return () => {\n cancelled = true\n namespace = undefined\n if (unmount !== undefined) void unmount()\n }\n }, 'dsh-deeppilot: report remote mount')\n\n const beginPairing = async (): Promise<PairingGrantSnapshot> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n const result = await namespace.beginPairing()\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'pair.qrFailed'))\n return result.value\n }\n\n const revokeDevice = async (deviceId: string): Promise<void> => {\n if (namespace === undefined) throw new Error(t(ctx, 'diag.remoteUnmounted'))\n const result = await namespace.revokeDevice(deviceId)\n if (!result.ok || result.value !== true) throw new Error(result.ok ? t(ctx, 'devices.revokeFailed') : (result.error.message ?? t(ctx, 'devices.revokeFailed')))\n await controller.refresh()\n }\n\n const setDeviceName = async (deviceId: string, customName: string | null): Promise<string | null> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n if (typeof namespace.setDeviceName !== 'function') {\n throw new Error(t(ctx, 'devices.renameStaleHost'))\n }\n const result = await namespace.setDeviceName(deviceId, customName)\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'devices.renameFailed'))\n await controller.refresh()\n return result.value\n }\n\n const sendTestPush = async (): Promise<PushTestResult> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n if (typeof namespace.testPush !== 'function') {\n throw new Error(t(ctx, 'push.staleHostPush'))\n }\n const result = await namespace.testPush()\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'push.pushFailed'))\n return result.value\n }\n\n const testRelayConnection = async (): Promise<RelayTestResult> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n if (typeof namespace.testRelay !== 'function') {\n throw new Error(t(ctx, 'push.staleHostPushRelay'))\n }\n const result = await namespace.testRelay()\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'push.relayBad'))\n return result.value\n }\n\n // Master switch: mirror the durable `enabled` field of the deeppilot\n // profile config entry shared with the Host half.\n const enabledStore = createSnapshotStore<EnabledState>({ status: 'loading', enabled: true })\n let scope: SettingsScopeLike | undefined = bindConfigForm(anyCtx)\n /** Adopters registered before attachScope runs, so a late-bound config form\n * still subscribes all. */\n const scopeAdoptions: Array<() => void> = []\n const adoptEnabled = (): void => {\n if (scope === undefined) return\n const snap = scope.getSnapshot()\n if (snap.status === 'ready' && snap.value !== undefined) {\n enabledStore.set({ status: 'ready', enabled: snap.value.enabled !== false })\n } else if (snap.status === 'unavailable') {\n enabledStore.set({ status: 'unavailable', enabled: true })\n }\n }\n scopeAdoptions.push(adoptEnabled)\n\n // Track the last scope-confirmed value so a rejected write can roll the\n // optimistic store back instead of leaving the UI in a state the Host never\n // accepted. Seed from adoptEnabled's result by reading the store.\n const lastConfirmedEnabled = (): boolean => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready' && snap.value !== undefined) return snap.value.enabled !== false\n // Pre-adopt fallback so the first flip still has a sane rollback target.\n return enabledStore.getSnapshot().enabled\n }\n const localEnabledStore = createSnapshotStore<LocalEnabledState>({ status: 'loading', enabled: true })\n const localPortStore = createSnapshotStore<LocalPortState>({ status: 'loading', value: DEFAULT_LOCAL_PORT })\n const lastConfirmedLocalEnabled = (): boolean => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready') return snap.value?.local?.enabled !== false\n return localEnabledStore.getSnapshot().enabled\n }\n const lastConfirmedLocalPort = (): number => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready') return normalizeLocalPort(snap.value?.local?.port)\n return localPortStore.getSnapshot().value\n }\n const lastConfirmedRemoteEnabled = (): boolean => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready') return snap.value?.remote?.enabled === true\n return remoteEnabledStore.getSnapshot().enabled\n }\n const lastConfirmedRemoteConnectionLimit = (): number => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready') return normalizeFunnelConnectionLimit(snap.value?.remote?.maxConnectionsPerSource)\n return remoteConnectionLimitStore.getSnapshot().value\n }\n\n const setDeepPilotEnabled = (value: boolean): void => {\n const previous = lastConfirmedEnabled()\n enabledStore.set({ status: 'ready', enabled: value })\n if (scope === undefined) return\n void scope.set('enabled', value).then(() => { /* next adoptEnabled will refresh */ }, (error: unknown) => {\n // Roll the store back so the switch reflects the durable truth, and\n // surface the failure: silent rejections used to leave a \"turned off\"\n // UI live with a still-on Host until the next unrelated change.\n enabledStore.set({ status: 'ready', enabled: previous })\n const message = error instanceof Error ? error.message : String(error)\n console.error('[deeppilot] failed to persist enabled=' + String(value) + ': ' + message)\n })\n }\n\n const adoptLocal = (): void => {\n if (scope === undefined) return\n const snap = scope.getSnapshot()\n if (snap.status === 'ready') {\n localEnabledStore.set({ status: 'ready', enabled: snap.value?.local?.enabled !== false })\n localPortStore.set({ status: 'ready', value: normalizeLocalPort(snap.value?.local?.port) })\n } else if (snap.status === 'unavailable') {\n localEnabledStore.set({ status: 'unavailable', enabled: true })\n localPortStore.set({ status: 'unavailable', value: DEFAULT_LOCAL_PORT })\n }\n }\n scopeAdoptions.push(adoptLocal)\n\n const setDeepPilotLocalEnabled = (value: boolean): void => {\n const previous = lastConfirmedLocalEnabled()\n localEnabledStore.set({ status: 'ready', enabled: value })\n if (scope === undefined) return\n const currentLocal = scope.getSnapshot().value?.local ?? {}\n void scope.set('local', { ...currentLocal, enabled: value }).then(() => {}, (error: unknown) => {\n localEnabledStore.set({ status: 'ready', enabled: previous })\n console.error('[deeppilot] failed to persist local.enabled=' + String(value) + ': ' + (error instanceof Error ? error.message : String(error)))\n })\n }\n\n const setDeepPilotLocalPort = async (value: number): Promise<void> => {\n const next = normalizeLocalPort(value)\n if (next !== value) throw new RangeError('local port must be an integer between 1024 and 65535')\n if (scope === undefined) throw new Error('settings scope unavailable')\n const previous = lastConfirmedLocalPort()\n localPortStore.set({ status: 'ready', value: next })\n const currentLocal = scope.getSnapshot().value?.local ?? {}\n try {\n await scope.set('local', { ...currentLocal, port: next })\n } catch (error) {\n localPortStore.set({ status: 'ready', value: previous })\n console.error('[deeppilot] failed to persist local.port=' + String(next) + ': ' + (error instanceof Error ? error.message : String(error)))\n throw error\n }\n }\n\n // Diagnostics toggle: defaults false, unlike enabled/local which default true.\n const debugStore = createSnapshotStore<DebugState>({ status: 'loading', enabled: false })\n const adoptDebug = (): void => {\n if (scope === undefined) return\n const snap = scope.getSnapshot()\n if (snap.status === 'ready') {\n debugStore.set({ status: 'ready', enabled: snap.value?.diagnostics?.debug === true })\n } else if (snap.status === 'unavailable') {\n debugStore.set({ status: 'unavailable', enabled: false })\n }\n }\n scopeAdoptions.push(adoptDebug)\n const lastConfirmedDebug = (): boolean => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready') return snap.value?.diagnostics?.debug === true\n return debugStore.getSnapshot().enabled\n }\n const setDeepPilotDebug = (value: boolean): void => {\n const previous = lastConfirmedDebug()\n debugStore.set({ status: 'ready', enabled: value })\n if (scope === undefined) return\n const currentDiagnostics = scope.getSnapshot().value?.diagnostics ?? {}\n void scope.set('diagnostics', { ...currentDiagnostics, debug: value }).then(() => {}, (error: unknown) => {\n debugStore.set({ status: 'ready', enabled: previous })\n console.error('[deeppilot] failed to persist diagnostics.debug=' + String(value) + ': ' + (error instanceof Error ? error.message : String(error)))\n })\n }\n\n const remoteEnabledStore = createSnapshotStore<RemoteEnabledState>({ status: 'loading', enabled: false })\n const remoteConnectionLimitStore = createSnapshotStore<RemoteConnectionLimitState>({\n status: 'loading',\n value: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE,\n })\n const adoptRemoteEnabled = (): void => {\n if (scope === undefined) return\n const snap = scope.getSnapshot()\n if (snap.status === 'ready') {\n remoteEnabledStore.set({ status: 'ready', enabled: snap.value?.remote?.enabled === true })\n remoteConnectionLimitStore.set({\n status: 'ready',\n value: normalizeFunnelConnectionLimit(snap.value?.remote?.maxConnectionsPerSource),\n })\n } else if (snap.status === 'unavailable') {\n remoteEnabledStore.set({ status: 'unavailable', enabled: false })\n remoteConnectionLimitStore.set({ status: 'unavailable', value: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE })\n }\n }\n scopeAdoptions.push(adoptRemoteEnabled)\n\n // Attach once every adopter is registered. The form is an optional\n // injection because the settings-page fiber may provide it later.\n const attachScope = (): void => {\n if (scope === undefined) return\n for (const adopt of scopeAdoptions) {\n scope.subscribe(adopt)\n adopt()\n }\n }\n attachScope()\n if (scope === undefined) {\n const bindScopeFrom = (sub: AnyCtx): void => {\n if (scope !== undefined) return\n scope = bindConfigForm(sub)\n attachScope()\n }\n ctx.inject(['configForms'], (sub) => { bindScopeFrom(sub as AnyCtx) })\n }\n\n const setDeepPilotRemoteEnabled = (value: boolean): void => {\n const previous = lastConfirmedRemoteEnabled()\n remoteEnabledStore.set({ status: 'ready', enabled: value })\n if (scope === undefined) return\n const currentRemote = scope.getSnapshot().value?.remote ?? {}\n void scope.set('remote', { ...currentRemote, enabled: value }).then(() => { /* next adopt refreshes */ }, (error: unknown) => {\n remoteEnabledStore.set({ status: 'ready', enabled: previous })\n const message = error instanceof Error ? error.message : String(error)\n console.error('[deeppilot] failed to persist remote.enabled=' + String(value) + ': ' + message)\n })\n }\n\n const setDeepPilotRemoteConnectionLimit = async (value: number): Promise<void> => {\n const next = normalizeFunnelConnectionLimit(value)\n if (next !== value) throw new RangeError('maxConnectionsPerSource must be an integer between 1 and 16')\n if (scope === undefined) throw new Error('settings scope unavailable')\n const previous = lastConfirmedRemoteConnectionLimit()\n remoteConnectionLimitStore.set({ status: 'ready', value: next })\n const currentRemote = scope.getSnapshot().value?.remote ?? {}\n try {\n await scope.set('remote', { ...currentRemote, maxConnectionsPerSource: next })\n } catch (error) {\n remoteConnectionLimitStore.set({ status: 'ready', value: previous })\n const message = error instanceof Error ? error.message : String(error)\n console.error('[deeppilot] failed to persist remote.maxConnectionsPerSource=' + String(next) + ': ' + message)\n throw error\n }\n }\n\n if (anyCtx.slots === undefined) {\n // locale/configForms/remote all have visible degradations when missing;\n // slots is the registration seam itself — a missing slot service means\n // the whole page is silently blank. Surface it loudly so the cause shows\n // up next to the other diagnostic lines.\n console.error('[deeppilot] settings slots service unavailable; the DeepPilot section will not appear')\n }\n anyCtx.slots?.inject('settings.section', () =>\n (anyCtx.slots as NonNullable<AnyCtx['slots']>).register({\n name: 'settings.section',\n id: 'deeppilot',\n order: 13,\n label: () => {\n const bind = anyCtx.locale?.bind('settings.deeppilot')\n return bind ? bind('nav') : 'DeepPilot'\n },\n locale: 'settings.deeppilot',\n inject: () => ({\n hooks: {\n deepPilotReport: store,\n deepPilotEnabled: enabledStore,\n deepPilotLocalEnabled: localEnabledStore,\n deepPilotLocalPort: localPortStore,\n deepPilotRemoteEnabled: remoteEnabledStore,\n deepPilotRemoteConnectionLimit: remoteConnectionLimitStore,\n deepPilotDebug: debugStore,\n },\n refresh: () => { void controller.refresh() },\n beginPairing,\n revokeDevice,\n setDeviceName,\n testRelay: testRelayConnection,\n testPush: sendTestPush,\n setDeepPilotEnabled,\n setDeepPilotLocalEnabled,\n setDeepPilotLocalPort,\n setDeepPilotRemoteEnabled,\n setDeepPilotRemoteConnectionLimit,\n setDeepPilotDebug,\n // Bound translation function for the page. The page never imports\n // t() directly so it can be re-supplied if the host swaps the\n // locale face at runtime (a feature today; exercised in tests).\n t: (key: string, vars?: Readonly<Record<string, unknown>>) => t(ctx, key, vars),\n }),\n }, DeepPilotSettingsPage),\n )\n // 导航图标:DSH 0.2.2 起设置壳声明 `settings.section.icon`,按与上面\n // `settings.section` 相同的 id 匹配。`inject` 跟随插槽声明的生命周期,\n // 旧宿主的壳不声明这个插槽,回调不会触发,导航行保留默认图标。\n // 壳不显示 `label`,图标自身也 aria-hidden,可读名称仍来自上面的 label。\n anyCtx.slots?.inject('settings.section.icon', () =>\n (anyCtx.slots as NonNullable<AnyCtx['slots']>).register({\n name: 'settings.section.icon',\n id: 'deeppilot',\n }, DeepPilotNavIcon),\n )\n}\n"],"ignoreList":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["h","useRef","h","h","useReducer","useState","useId","useRef","t","deviceLabel","deviceLabelOf","visibleDevices","visibleDevicesOf","Switch","Button","h","registerDeepPilotLocale"],"sources":["../src/client/snapshot-store.ts","../src/tailscale-version.ts","../src/device-auth.ts","../src/report-wire.ts","../src/client/report-mount.ts","../src/client/i18n.ts","../src/client/styles.ts","../src/client/settings-icons.ts","../src/client/device-actions.ts","../node_modules/qrcode/lib/can-promise.js","../node_modules/qrcode/lib/core/utils.js","../node_modules/qrcode/lib/core/error-correction-level.js","../node_modules/qrcode/lib/core/bit-buffer.js","../node_modules/qrcode/lib/core/bit-matrix.js","../node_modules/qrcode/lib/core/alignment-pattern.js","../node_modules/qrcode/lib/core/finder-pattern.js","../node_modules/qrcode/lib/core/mask-pattern.js","../node_modules/qrcode/lib/core/error-correction-code.js","../node_modules/qrcode/lib/core/galois-field.js","../node_modules/qrcode/lib/core/polynomial.js","../node_modules/qrcode/lib/core/reed-solomon-encoder.js","../node_modules/qrcode/lib/core/version-check.js","../node_modules/qrcode/lib/core/regex.js","../node_modules/qrcode/lib/core/mode.js","../node_modules/qrcode/lib/core/version.js","../node_modules/qrcode/lib/core/format-info.js","../node_modules/qrcode/lib/core/numeric-data.js","../node_modules/qrcode/lib/core/alphanumeric-data.js","../node_modules/qrcode/lib/core/byte-data.js","../node_modules/qrcode/lib/core/kanji-data.js","../node_modules/dijkstrajs/dijkstra.js","../node_modules/qrcode/lib/core/segments.js","../node_modules/qrcode/lib/core/qrcode.js","../node_modules/qrcode/lib/renderer/utils.js","../node_modules/qrcode/lib/renderer/canvas.js","../node_modules/qrcode/lib/renderer/svg-tag.js","../node_modules/qrcode/lib/browser.js","../src/pairing-qr.ts","../src/client/pairing-panel.ts","../src/funnel-policy.ts","../src/local-policy.ts","../src/client/settings-props.ts","../src/client/settings-view-models.ts","../src/client/settings-page.ts","../src/client/nav-icon.ts","../src/client/config-form.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Tiny observable snapshot store consumed by the harness slot renderer's\n * `useSyncExternalStore` hooks.\n *\n * Kept local because the rc.2 browser module table does not publish\n * `@deepseek-ai/dsh-client-store` for external plugins. The generated bundle\n * therefore has no unavailable runtime dependency.\n */\nexport interface SnapshotStore<T> {\n getSnapshot(): T\n subscribe(listener: () => void): () => void\n set(value: T): void\n}\n\nexport function createSnapshotStore<T>(initial: T): SnapshotStore<T> {\n let snapshot = initial\n const listeners = new Set<() => void>()\n return {\n getSnapshot: () => snapshot,\n subscribe(listener) {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n set(value) {\n if (Object.is(value, snapshot)) return\n snapshot = value\n for (const listener of listeners) listener()\n },\n }\n}\n","/**\n * 内嵌 helper 上报的 tailscale.com 模块版本。\n *\n * 版本的唯一来源是 helper 启动事件(`helper/main.go` 读 Go 构建信息里的\n * `tailscale.com` 依赖版本),不是 go.mod、也不是插件常量:用户可能通过\n * `remote.helperPath` 换成自己编译的 helper,界面必须显示实际在跑的那一个。\n *\n * 两条边界都要守卫:\n * - 宿主侧 `parseHelperEvent` 把 helper 的 stdout 当成不可信输入,格式不对\n * 就丢弃,避免把任意文本渲染进设置页;\n * - 设置页侧 `reportSchema` 同样校验 Host RPC 返回值,旧 Host 不带该字段\n * 时保持 undefined(页面显示「未获取」),不当作错误。\n *\n * 接受 Go 模块版本形态:`v1.104.2`、`v1.104.2-pre.1`、\n * `v0.0.0-20260101000000-abcdef123456`。长度上限防止异常输入撑爆界面。\n */\nexport const TAILSCALE_VERSION_PATTERN = /^v?\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]{1,64})?$/\n\nconst MAX_TAILSCALE_VERSION_LENGTH = 80\n\n/** 判断外部输入是否是合法的 Tailscale 模块版本字符串。 */\nexport function isTailscaleVersion(value: unknown): value is string {\n return typeof value === 'string' &&\n value.length <= MAX_TAILSCALE_VERSION_LENGTH &&\n TAILSCALE_VERSION_PATTERN.test(value)\n}\n","import {\n createHash,\n createPublicKey,\n randomBytes,\n timingSafeEqual,\n verify,\n type KeyObject,\n} from 'node:crypto'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { formatLogLine } from './diagnostics.ts'\n\nexport function getPairingCodeTtlMs(): number {\n return Number(process.env.DEEPPILOT_PAIRING_TTL_MS) || 5 * 60_000\n}\nexport const AUTH_CHALLENGE_TTL_MS = 30_000\n\nexport const DEVICE_SCOPES = [\n 'sessions.read',\n 'prompt.send',\n 'sessions.manage',\n 'interactions.respond',\n 'notifications.register',\n 'schedule.manage',\n] as const\n\nexport type DeviceScope = (typeof DEVICE_SCOPES)[number]\n\nexport const DEFAULT_DEVICE_SCOPES: readonly DeviceScope[] = DEVICE_SCOPES\n\nexport interface PairingGrant {\n code: string\n expiresAt: number\n audience?: string\n}\n\nexport async function loadOrCreateHostAudience(path: string): Promise<string> {\n try {\n const existing = (await readFile(path, 'utf8')).trim()\n if (/^deeppilot:[A-Za-z0-9_-]{22}$/.test(existing)) return existing\n throw new Error(`host audience is malformed at ${path}`)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n }\n const audience = 'deeppilot:' + randomBytes(16).toString('base64url')\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, audience + '\\n', { mode: 0o600 })\n // 新建 Host 身份意味着 audience 变了:所有此前配对的设备都会在下一步\n // 认证失败(audience-mismatch)。这是「手机突然全部要重新配对」最直接的\n // 证据,必须留一行;只记事实与路径,不记 audience 原文(可被冒充)。\n console.log(formatLogLine('info', 'host identity created: ' + path + ' (previously paired devices must pair again)'))\n return audience\n}\n\nexport interface AuthChallenge {\n nonce: string\n audience: string\n issuedAt: number\n expiresAt: number\n}\n\nexport interface AuthProofFields extends AuthChallenge {\n deviceId: string\n deviceName: string\n appVersion: string\n resumeCursor?: number\n}\n\nfunction b64urlText(value: string): string {\n return Buffer.from(value, 'utf8').toString('base64url')\n}\n\n/**\n * Cross-language signature input. Text fields are base64url encoded before\n * joining so names cannot create ambiguous separators. Decimal timestamps\n * and cursor values are finite integers, or `-` when the cursor is absent.\n */\nexport function canonicalAuthChallenge(fields: AuthProofFields): Buffer {\n const cursor = fields.resumeCursor === undefined ? '-' : String(fields.resumeCursor)\n return Buffer.from([\n 'deeppilot-auth-v2',\n `device-id:${b64urlText(fields.deviceId)}`,\n `nonce:${fields.nonce}`,\n `audience:${b64urlText(fields.audience)}`,\n `issued-at:${fields.issuedAt}`,\n `expires-at:${fields.expiresAt}`,\n `device-name:${b64urlText(fields.deviceName)}`,\n `app-version:${b64urlText(fields.appVersion)}`,\n `resume-cursor:${cursor}`,\n ].join('\\n'), 'utf8')\n}\n\n/** Accept only an uncompressed ANSI X9.63 P-256 public key (65 bytes). */\nexport function parseP256PublicKey(encoded: string): { key: KeyObject; raw: Buffer } {\n const raw = Buffer.from(encoded, 'base64url')\n if (raw.length !== 65 || raw[0] !== 0x04) {\n throw new TypeError('publicKey must be an uncompressed P-256 X9.63 key')\n }\n // SubjectPublicKeyInfo prefix for id-ecPublicKey / prime256v1 followed by\n // the 65-byte uncompressed point.\n const spkiPrefix = Buffer.from('3059301306072a8648ce3d020106082a8648ce3d030107034200', 'hex')\n const key = createPublicKey({ key: Buffer.concat([spkiPrefix, raw]), format: 'der', type: 'spki' })\n if (key.asymmetricKeyType !== 'ec' || key.asymmetricKeyDetails?.namedCurve !== 'prime256v1') {\n throw new TypeError('publicKey must use P-256')\n }\n return { key, raw }\n}\n\nexport function deviceIdForPublicKey(publicKey: string): string {\n const { raw } = parseP256PublicKey(publicKey)\n return createHash('sha256').update(raw).digest('base64url')\n}\n\nexport function fingerprintForPublicKey(publicKey: string): string {\n const { raw } = parseP256PublicKey(publicKey)\n return createHash('sha256').update(raw).digest('hex')\n}\n\nexport function verifyAuthProof(publicKey: string, fields: AuthProofFields, signature: string): boolean {\n try {\n const { key } = parseP256PublicKey(publicKey)\n const der = Buffer.from(signature, 'base64url')\n if (der.length < 64 || der.length > 80) return false\n return verify('sha256', canonicalAuthChallenge(fields), key, der)\n } catch {\n return false\n }\n}\n\nexport function normalizeDeviceScopes(value: unknown): DeviceScope[] {\n if (!Array.isArray(value)) return [...DEFAULT_DEVICE_SCOPES]\n const allowed = new Set<string>(DEVICE_SCOPES)\n return [...new Set(value.filter((scope): scope is DeviceScope => typeof scope === 'string' && allowed.has(scope)))]\n}\n\n/**\n * 0.8.3 之前的「全部权限」:当时还没有 `schedule.manage`。App 配对时一直申请\n * DeviceScope 的全部取值,设置页也没有收窄权限的入口,所以存量记录恰好等于这五项,\n * 只说明「配对时这项权限还不存在」,不是有意关闭。\n */\nconst LEGACY_FULL_SCOPES: readonly DeviceScope[] = [\n 'sessions.read',\n 'prompt.send',\n 'sessions.manage',\n 'interactions.respond',\n 'notifications.register',\n]\n\n/**\n * 存量设备权限升级:恰好等于旧版全部权限时补上之后新增的默认权限,返回新列表;\n * 其余情况(含任何非完整集合)返回 null,原样保留。只放宽「旧版全量」这一种形态,\n * 避免把将来可能出现的、有意收窄过的记录一并放开。\n */\nexport function upgradeLegacyFullScopes(value: unknown): DeviceScope[] | null {\n if (!Array.isArray(value)) return null\n const current = new Set(value)\n if (current.size !== LEGACY_FULL_SCOPES.length) return null\n if (!LEGACY_FULL_SCOPES.every((scope) => current.has(scope))) return null\n return [...DEFAULT_DEVICE_SCOPES]\n}\n\n/** One active, single-use pairing grant per plugin runtime. */\nexport class PairingCodeManager {\n private active: PairingGrant | null = null\n\n issue(now = Date.now()): PairingGrant {\n const grant = {\n code: randomBytes(24).toString('base64url'),\n expiresAt: now + getPairingCodeTtlMs(),\n }\n this.active = grant\n return { ...grant }\n }\n\n consume(presented: string, now = Date.now()): boolean {\n const active = this.active\n if (active === null || now > active.expiresAt) {\n this.active = null\n return false\n }\n const expected = Buffer.from(active.code)\n const actual = Buffer.from(presented)\n const matches = expected.length === actual.length && timingSafeEqual(expected, actual)\n if (matches) this.active = null\n return matches\n }\n\n invalidate(): void {\n this.active = null\n }\n}\n\nexport function createAuthChallenge(audience: string, now = Date.now()): AuthChallenge {\n return {\n nonce: randomBytes(24).toString('base64url'),\n audience,\n issuedAt: now,\n expiresAt: now + AUTH_CHALLENGE_TTL_MS,\n }\n}\n","/**\n * Wire contract for the DeepPilot report Remote (`deeppilot/report`).\n *\n * The web settings page needs the bridge's live facts (paired devices,\n * connections, token state) — those live Host-side. This module is the single\n * source both halves share: the strict result codec (hand-rolled, so the\n * client bundle needs no schema library) and the exact descriptor object.\n *\n * @module dsh-deeppilot/report-wire\n */\n\nimport type { InvocationDescriptor, TypertCodec, TypertRemoteContribution, TypertSchema } from '@deepseek-ai/dsh-typert-protocol'\nimport { isTailscaleVersion } from './tailscale-version.ts'\nimport { DEVICE_SCOPES, normalizeDeviceScopes, type DeviceScope } from './device-auth.ts'\n\nexport interface PairingGrantSnapshot {\n code: string\n expiresAt: number\n audience: string\n}\n\n/** One paired device row in the report. */\nexport interface ReportDevice {\n deviceId: string\n /** Effective operator-facing name: customName when set, otherwise the app-reported name. */\n deviceName: string\n /** User-assigned label; absent means the app-reported name is in use. */\n customName?: string\n appVersion: string\n firstSeenTs: number\n lastSeenTs: number\n fingerprint: string\n scopes: DeviceScope[]\n revokedAt?: number\n /** Present once the device registered an APNs token (token itself never leaves the host). */\n apns?: { environment: 'development' | 'production'; updatedAt: number }\n}\n\n/** One step of the relay connectivity self-test. */\nexport interface RelayTestStep {\n id: 'health' | 'enroll'\n ok: boolean\n message: string\n latencyMs?: number\n}\n\n/** Result of deeppilot/testRelay. */\nexport interface RelayTestResult {\n url: string\n overall: 'ok' | 'failed'\n tokenIssued: boolean\n steps: RelayTestStep[]\n}\n\n/** Per-device delivery result of deeppilot/testPush. */\nexport interface PushTestDeviceResult {\n name: string\n environment: string\n /** sent | invalid-token | failed — mirrors the dispatch outcome contract. */\n outcome: string\n /** Apple's raw rejection reason when present (BadDeviceToken, …). */\n reason?: string\n /** First 10 hex chars of the stored token, for freshness verification. */\n tokenFingerprint?: string\n}\n\n/**\n * 设置页「连接诊断」区块展示的一条最近失败。\n *\n * 只携带可安全展示的结构化事实:类型、分因、时间、来源哈希(auditLabel\n * 的 12 位十六进制,绝不是原始 IP)、可选 attemptId / 关闭码 / 耗时。\n * 配对码、公钥、APNs token、消息正文永远不进入这里。\n */\nexport interface ReportDiagnosticFailure {\n ts: number\n kind: string\n reason: string\n attemptId?: string\n source?: string\n closeCode?: number\n durationMs?: number\n}\n\n/** 连接诊断快照;不包含 debug 开关状态。 */\nexport interface ReportDiagnostics {\n /** 插件 apply() 的启动时刻。 */\n startedAt: number\n /** 最近失败事件(时间升序,最多 20 条)。 */\n recentFailures: ReportDiagnosticFailure[]\n}\n\nexport interface PushTestResult {\n transport: 'apns' | 'relay' | 'none'\n /** sent = at least one accepted delivery; no-targets / not-configured / failed. */\n overall: 'sent' | 'failed' | 'no-targets' | 'not-configured'\n message?: string\n results: PushTestDeviceResult[]\n}\n\n/** Everything the settings page renders for the bridge. */\nexport interface DeepPilotReport {\n protocolVersion: number\n serverVersion: string\n /** Host plugin version (from package.json). Same value as serverVersion,\n * surfaced under a stable name so the wire contract does not change if\n * the legacy field is ever repurposed. */\n pluginVersion: string\n /** True once the host's background GitHub check has confirmed a newer\n * stable release exists. Undefined / false ⇒ the UI shows only the\n * version line, never the \"new version\" hint. */\n updateAvailable?: boolean\n /** GitHub release page URL, when an update is available. */\n releaseUrl?: string\n /** Whether the master bridge switch is on. */\n enabled: boolean\n /** Absolute protocol-v2 identity registry path. */\n identityPath: string\n /** Whether host identity and the device registry are ready. */\n pairingReady: boolean\n /** Currently connected phone sockets. */\n activeConnections: number\n historyBufferMax: number\n /** Private IPv4 candidates for local QR pairing. */\n lanAddresses: string[]\n /** Independent TLS-only LAN listener; this never represents DSH's own web port. */\n local: {\n phase: 'disabled' | 'starting' | 'online' | 'error' | 'stopped'\n port: number\n endpoints: string[]\n /** `sha256:` SPKI pin of the LAN certificate; present while `online`. */\n tlsFingerprint?: string\n /** The LAN private key was recreated this run: paired LAN devices must pair again. */\n tlsIdentityRegenerated?: boolean\n message?: string\n updatedAt: number\n }\n remote: {\n provider: 'tailscale-funnel'\n phase: 'disabled' | 'starting' | 'login_required' | 'online' | 'error' | 'unavailable' | 'stopped'\n publicURL?: string\n authURL?: string\n message?: string\n /**\n * 内嵌 helper 自报的 tailscale.com 模块版本(如 `v1.104.2`)。可选:\n * 远程连接未启用、helper 缺失或尚未启动时 Host 不带这个字段,设置页\n * 显示「未获取」;旧 Host 同样不带,页面不能因此报错。\n */\n tailscaleVersion?: string\n updatedAt: number\n }\n devices: ReportDevice[]\n /**\n * 连接诊断。可选:旧 Host 不返回时设置页整块跳过,不当作错误。\n * 这是「最近失败」的唯一 report 通道(health 只服务手机)。\n */\n diagnostics?: ReportDiagnostics\n}\n\n/** The npm package identity both contribution registrations claim. */\nexport const REPORT_REMOTE_PACKAGE = 'dsh-deeppilot'\n\n/** Canonical `<namespace>/<method>` endpoint of the report Remote. */\nexport const REPORT_ENDPOINT = 'deeppilot/report'\n\nexport const BEGIN_PAIRING_ENDPOINT = 'deeppilot/beginPairing'\nexport const REVOKE_DEVICE_ENDPOINT = 'deeppilot/revokeDevice'\nexport const SET_DEVICE_NAME_ENDPOINT = 'deeppilot/setDeviceName'\nexport const SET_DEVICE_SCOPES_ENDPOINT = 'deeppilot/setDeviceScopes'\n\nfunction reject(field: string): never {\n throw new TypeError(`deeppilot/report result: invalid ${field}`)\n}\n\nfunction str(source: Record<string, unknown>, key: string, field: string): string {\n const value = source[key]\n if (typeof value !== 'string') reject(field)\n return value\n}\n\n/**\n * Non-negative integer: counters and timestamps (activeConnections,\n * historyBufferMax, updatedAt, lastSeenTs, protocolVersion, etc.). A bare\n * `typeof number` check accepts 1.5, -1, and 1e20 — all of which then\n * surface verbatim on the settings page and break any sort or arithmetic\n * the UI does.\n */\nfunction int(source: Record<string, unknown>, key: string, field: string): number {\n const value = source[key]\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n !Number.isInteger(value) ||\n value < 0\n ) reject(field)\n return value\n}\nfunction bool(source: Record<string, unknown>, key: string, field: string): boolean {\n const value = source[key]\n if (typeof value !== 'boolean') reject(field)\n return value\n}\nfunction rec(value: unknown, field: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) reject(field)\n return value as Record<string, unknown>\n}\n\nfunction parseDevice(value: unknown): ReportDevice {\n const s = rec(value, 'device')\n let apns: ReportDevice['apns']\n if (s.apns !== undefined) {\n const a = rec(s.apns, 'device.apns')\n const environment = str(a, 'environment', 'device.apns.environment')\n if (environment !== 'development' && environment !== 'production') reject('device.apns.environment')\n apns = { environment, updatedAt: int(a, 'updatedAt', 'device.apns.updatedAt') }\n }\n const customName = s.customName\n if (customName !== undefined && (\n typeof customName !== 'string' ||\n customName.length === 0 ||\n customName.length > 64 ||\n customName.trim() !== customName ||\n /[\\u0000-\\u001f\\u007f-\\u009f]/u.test(customName)\n )) reject('device.customName')\n return {\n deviceId: str(s, 'deviceId', 'device.deviceId'),\n deviceName: str(s, 'deviceName', 'device.deviceName'),\n ...(typeof customName === 'string' ? { customName } : {}),\n appVersion: str(s, 'appVersion', 'device.appVersion'),\n firstSeenTs: int(s, 'firstSeenTs', 'device.firstSeenTs'),\n lastSeenTs: int(s, 'lastSeenTs', 'device.lastSeenTs'),\n fingerprint: str(s, 'fingerprint', 'device.fingerprint'),\n scopes: normalizeDeviceScopes(s.scopes),\n ...(s.revokedAt !== undefined ? { revokedAt: int(s, 'revokedAt', 'device.revokedAt') } : {}),\n ...(apns ? { apns } : {}),\n }\n}\n\nfunction parseRemote(value: unknown): DeepPilotReport['remote'] {\n const s = rec(value, 'remote')\n const provider = str(s, 'provider', 'remote.provider')\n const phase = str(s, 'phase', 'remote.phase')\n if (provider !== 'tailscale-funnel') reject('remote.provider')\n const phases = ['disabled', 'starting', 'login_required', 'online', 'error', 'unavailable', 'stopped']\n if (!phases.includes(phase)) reject('remote.phase')\n const publicURL = s.publicURL\n const authURL = s.authURL\n const message = s.message\n const tailscaleVersion = s.tailscaleVersion\n if (publicURL !== undefined && typeof publicURL !== 'string') reject('remote.publicURL')\n if (authURL !== undefined && typeof authURL !== 'string') reject('remote.authURL')\n if (message !== undefined && typeof message !== 'string') reject('remote.message')\n // 页面直接渲染这个字符串:只接受 Go 模块版本形态,坏值拒绝整份报告,\n // 而不是把任意文本带进设置页。\n if (tailscaleVersion !== undefined && !isTailscaleVersion(tailscaleVersion)) reject('remote.tailscaleVersion')\n return {\n provider,\n phase: phase as DeepPilotReport['remote']['phase'],\n ...(typeof publicURL === 'string' ? { publicURL } : {}),\n ...(typeof authURL === 'string' ? { authURL } : {}),\n ...(typeof message === 'string' ? { message } : {}),\n ...(typeof tailscaleVersion === 'string' ? { tailscaleVersion } : {}),\n updatedAt: int(s, 'updatedAt', 'remote.updatedAt'),\n }\n}\n\nfunction parseLocal(value: unknown): DeepPilotReport['local'] {\n const s = rec(value, 'local')\n const phase = str(s, 'phase', 'local.phase')\n const phases = ['disabled', 'starting', 'online', 'error', 'stopped']\n if (!phases.includes(phase)) reject('local.phase')\n const endpoints = s.endpoints\n if (!Array.isArray(endpoints) || endpoints.some((entry) => typeof entry !== 'string')) reject('local.endpoints')\n const message = s.message\n if (message !== undefined && typeof message !== 'string') reject('local.message')\n const tlsFingerprint = s.tlsFingerprint\n if (tlsFingerprint !== undefined && typeof tlsFingerprint !== 'string') reject('local.tlsFingerprint')\n const tlsIdentityRegenerated = s.tlsIdentityRegenerated\n if (tlsIdentityRegenerated !== undefined && typeof tlsIdentityRegenerated !== 'boolean') reject('local.tlsIdentityRegenerated')\n return {\n phase: phase as DeepPilotReport['local']['phase'],\n port: int(s, 'port', 'local.port'),\n endpoints: endpoints as string[],\n ...(typeof tlsFingerprint === 'string' ? { tlsFingerprint } : {}),\n ...(tlsIdentityRegenerated === true ? { tlsIdentityRegenerated: true } : {}),\n ...(typeof message === 'string' ? { message } : {}),\n updatedAt: int(s, 'updatedAt', 'local.updatedAt'),\n }\n}\n\nfunction parseRelayTestStep(value: unknown): RelayTestStep {\n const st = rec(value, 'step')\n const id = str(st, 'id', 'step.id')\n if (id !== 'health' && id !== 'enroll') reject('step.id')\n const latencyMs = st.latencyMs\n if (latencyMs !== undefined) {\n // Same int() check the report uses for counters: latency is always a\n // non-negative whole-millisecond number; a NaN/Infinity/negative arrives\n // from a buggy host and must not silently render as `(NaNms)`.\n if (\n typeof latencyMs !== 'number' ||\n !Number.isFinite(latencyMs) ||\n !Number.isInteger(latencyMs) ||\n latencyMs < 0\n ) reject('step.latencyMs')\n }\n return {\n id,\n ok: bool(st, 'ok', 'step.ok'),\n message: str(st, 'message', 'step.message'),\n ...(typeof latencyMs === 'number' ? { latencyMs } : {}),\n }\n}\n\nfunction parseRelayTestResult(value: unknown): RelayTestResult {\n const s = rec(value, 'result')\n const overall = str(s, 'overall', 'overall')\n if (overall !== 'ok' && overall !== 'failed') reject('overall')\n const stepsRaw = s.steps\n if (!Array.isArray(stepsRaw)) reject('steps')\n return {\n url: str(s, 'url', 'url'),\n overall,\n tokenIssued: bool(s, 'tokenIssued', 'tokenIssued'),\n steps: (stepsRaw as unknown[]).map(parseRelayTestStep),\n }\n}\n\nfunction parsePushTestResult(value: unknown): PushTestResult {\n const s = rec(value, 'result')\n const transport = str(s, 'transport', 'transport')\n if (transport !== 'apns' && transport !== 'relay' && transport !== 'none') reject('transport')\n const overall = str(s, 'overall', 'overall')\n const overalls = ['sent', 'failed', 'no-targets', 'not-configured']\n if (!overalls.includes(overall)) reject('overall')\n const resultsRaw = s.results\n if (!Array.isArray(resultsRaw)) reject('results')\n const results = (resultsRaw as unknown[]).map((value) => {\n const r = rec(value, 'device result')\n const reason = r.reason\n const tokenFingerprint = r.tokenFingerprint\n return {\n name: str(r, 'name', 'result.name'),\n environment: str(r, 'environment', 'result.environment'),\n outcome: str(r, 'outcome', 'result.outcome'),\n ...(typeof reason === 'string' && reason.length > 0 ? { reason } : {}),\n ...(typeof tokenFingerprint === 'string' && /^[0-9a-f]{10}$/.test(tokenFingerprint)\n ? { tokenFingerprint }\n : {}),\n }\n })\n const message = s.message\n return {\n transport,\n overall: overall as PushTestResult['overall'],\n ...(typeof message === 'string' && message.length > 0 ? { message } : {}),\n results,\n }\n}\n\nfunction parseDiagnosticFailure(value: unknown): ReportDiagnosticFailure {\n const s = rec(value, 'diagnostics.recentFailures[]')\n // kind / reason 是代码内枚举常量;这里收敛字符集与长度,防止上游把\n // 任意文本(路径、IP、错误消息)塞进设置页。\n const kind = str(s, 'kind', 'diagnostics.kind')\n if (!/^[a-z][a-z0-9-]{0,47}$/.test(kind)) reject('diagnostics.kind')\n const reason = str(s, 'reason', 'diagnostics.reason')\n if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(reason)) reject('diagnostics.reason')\n const attemptId = s.attemptId\n if (attemptId !== undefined && (typeof attemptId !== 'string' || !/^[A-Za-z0-9_-]{1,16}$/.test(attemptId))) {\n reject('diagnostics.attemptId')\n }\n const source = s.source\n if (source !== undefined && (typeof source !== 'string' || !/^[0-9a-f]{8,64}$/.test(source))) {\n reject('diagnostics.source')\n }\n const closeCode = s.closeCode\n if (closeCode !== undefined && (typeof closeCode !== 'number' || !Number.isInteger(closeCode))) {\n reject('diagnostics.closeCode')\n }\n const durationMs = s.durationMs\n if (durationMs !== undefined && (typeof durationMs !== 'number' || !Number.isFinite(durationMs) || durationMs < 0)) {\n reject('diagnostics.durationMs')\n }\n return {\n ts: int(s, 'ts', 'diagnostics.ts'),\n kind,\n reason,\n ...(typeof attemptId === 'string' ? { attemptId } : {}),\n ...(typeof source === 'string' ? { source } : {}),\n ...(typeof closeCode === 'number' ? { closeCode } : {}),\n ...(typeof durationMs === 'number' ? { durationMs: Math.round(durationMs) } : {}),\n }\n}\n\nfunction parseDiagnostics(value: unknown): ReportDiagnostics {\n const s = rec(value, 'diagnostics')\n const failures = s.recentFailures\n if (!Array.isArray(failures)) reject('diagnostics.recentFailures')\n // 页面上是「最近失败」列表,20 条足够;硬上限防止坏 Host 撑爆 UI。\n if (failures.length > 20) reject('diagnostics.recentFailures')\n return {\n startedAt: int(s, 'startedAt', 'diagnostics.startedAt'),\n recentFailures: (failures as unknown[]).map(parseDiagnosticFailure),\n }\n}\n\nfunction parseReport(value: unknown): DeepPilotReport {\n const s = rec(value, 'report')\n const devices = s.devices\n const lanAddresses = s.lanAddresses\n if (!Array.isArray(devices)) reject('devices')\n if (!Array.isArray(lanAddresses) || lanAddresses.some((value) => typeof value !== 'string')) reject('lanAddresses')\n // Update fields are optional: an older Host (without the background\n // GitHub check) won't include them, and the UI must keep rendering.\n const releaseUrl = s.releaseUrl\n return {\n protocolVersion: int(s, 'protocolVersion', 'protocolVersion'),\n serverVersion: str(s, 'serverVersion', 'serverVersion'),\n pluginVersion: str(s, 'pluginVersion', 'pluginVersion'),\n ...(s.updateAvailable === true ? { updateAvailable: true } : {}),\n ...(typeof releaseUrl === 'string' && releaseUrl.length > 0\n ? { releaseUrl } : {}),\n enabled: bool(s, 'enabled', 'enabled'),\n identityPath: str(s, 'identityPath', 'identityPath'),\n pairingReady: bool(s, 'pairingReady', 'pairingReady'),\n activeConnections: int(s, 'activeConnections', 'activeConnections'),\n historyBufferMax: int(s, 'historyBufferMax', 'historyBufferMax'),\n lanAddresses: lanAddresses as string[],\n local: parseLocal(s.local),\n remote: parseRemote(s.remote),\n devices: (devices as unknown[]).map(parseDevice),\n // 旧 Host 没有这个字段:保持可选,设置页整块跳过。\n ...(s.diagnostics !== undefined ? { diagnostics: parseDiagnostics(s.diagnostics) } : {}),\n }\n}\n\nexport const reportSchema: TypertSchema<DeepPilotReport> = { parse: parseReport }\n\nexport const relayTestSchema: TypertSchema<RelayTestResult> = { parse: parseRelayTestResult }\n\nexport const pushTestSchema: TypertSchema<PushTestResult> = { parse: parsePushTestResult }\n\nexport const pairingGrantSchema: TypertSchema<PairingGrantSnapshot> = {\n parse(value: unknown): PairingGrantSnapshot {\n const s = rec(value, 'pairing grant')\n const code = str(s, 'code', 'pairingGrant.code')\n if (code.length < 32) reject('pairingGrant.code')\n return {\n code,\n expiresAt: int(s, 'expiresAt', 'pairingGrant.expiresAt'),\n audience: str(s, 'audience', 'pairingGrant.audience'),\n }\n },\n}\n\nconst deviceIdSchema: TypertSchema<string> = {\n parse(value: unknown): string {\n if (typeof value !== 'string' || !/^[A-Za-z0-9_-]{43}$/.test(value)) reject('deviceId')\n return value\n },\n}\n\nconst customNameSchema: TypertSchema<string | null> = {\n parse(value: unknown): string | null {\n if (value === null) return null\n if (typeof value !== 'string') reject('customName')\n const trimmed = value.trim()\n if (trimmed.length === 0 || trimmed.length > 64 || /[\\u0000-\\u001f\\u007f-\\u009f]/u.test(value)) reject('customName')\n return trimmed\n },\n}\n\nconst scopesSchema: TypertSchema<DeviceScope[]> = {\n parse(value: unknown): DeviceScope[] {\n if (!Array.isArray(value) || value.some((scope) => typeof scope !== 'string' || !DEVICE_SCOPES.includes(scope as DeviceScope))) {\n reject('scopes')\n }\n return normalizeDeviceScopes(value)\n },\n}\n\nconst booleanSchema: TypertSchema<boolean> = {\n parse(value: unknown): boolean {\n if (typeof value !== 'boolean') reject('boolean')\n return value\n },\n}\n\n/** The rc.2 Gateway materializes each strict codec through `create()`. */\nfunction strictCodec<T>(typeSymbol: string, schema: TypertSchema<T>): TypertCodec {\n return {\n mode: 'strict',\n typeSymbol,\n create: () => schema,\n }\n}\n\n/**\n * Connectivity self-test for the push relay: health probe plus (when an\n * enroll key is on file) a real enrollment round-trip. Doubles as repair —\n * a token it issues is cached by the bridge.\n */\nexport const TEST_RELAY_ENDPOINT = 'deeppilot/testRelay'\n\n/**\n * Real-delivery push test: forces one synthetic notification down the active\n * push pathway to every registered device, ignoring connected/muted filters —\n * an explicit user action must always be able to prove the pipeline works.\n */\nexport const TEST_PUSH_ENDPOINT = 'deeppilot/testPush'\n\nexport const REPORT_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${REPORT_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'report',\n invocation: { kind: 'direct' },\n parameters: [],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeepPilotReport`, reportSchema),\n}\n\nexport const BEGIN_PAIRING_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${BEGIN_PAIRING_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'beginPairing',\n invocation: { kind: 'direct' },\n parameters: [],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#PairingGrantSnapshot`, pairingGrantSchema),\n}\n\nexport const REVOKE_DEVICE_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${REVOKE_DEVICE_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'revokeDevice',\n invocation: { kind: 'direct' },\n parameters: [{\n name: 'deviceId',\n wire: 'deviceId',\n source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceId`, deviceIdSchema),\n }],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#Boolean`, booleanSchema),\n}\n\nexport const SET_DEVICE_NAME_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${SET_DEVICE_NAME_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'setDeviceName',\n invocation: { kind: 'direct' },\n parameters: [\n {\n name: 'deviceId', wire: 'deviceId', source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceId`, deviceIdSchema),\n },\n {\n name: 'customName', wire: 'customName', source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#CustomDeviceName`, customNameSchema),\n },\n ],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#CustomDeviceName`, customNameSchema),\n}\n\nexport const SET_DEVICE_SCOPES_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${SET_DEVICE_SCOPES_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'setDeviceScopes',\n invocation: { kind: 'direct' },\n parameters: [\n {\n name: 'deviceId', wire: 'deviceId', source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceId`, deviceIdSchema),\n },\n {\n name: 'scopes', wire: 'scopes', source: 'json',\n codec: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceScopes`, scopesSchema),\n },\n ],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#DeviceScopes`, scopesSchema),\n}\n\nexport const TEST_RELAY_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${TEST_RELAY_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'testRelay',\n invocation: { kind: 'direct' },\n parameters: [],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#RelayTestResult`, relayTestSchema),\n}\n\nexport const TEST_PUSH_DESCRIPTOR: InvocationDescriptor = {\n id: `${REPORT_REMOTE_PACKAGE}#${TEST_PUSH_ENDPOINT}`,\n service: 'deeppilotReport',\n namespace: 'deeppilot',\n method: 'testPush',\n invocation: { kind: 'direct' },\n parameters: [],\n result: strictCodec(`${REPORT_REMOTE_PACKAGE}#PushTestResult`, pushTestSchema),\n}\n\nconst INVOCATION_DESCRIPTORS = [\n REPORT_DESCRIPTOR,\n BEGIN_PAIRING_DESCRIPTOR,\n REVOKE_DEVICE_DESCRIPTOR,\n SET_DEVICE_NAME_DESCRIPTOR,\n SET_DEVICE_SCOPES_DESCRIPTOR,\n TEST_RELAY_DESCRIPTOR,\n TEST_PUSH_DESCRIPTOR,\n]\n\nexport const REPORT_HOST_CONTRIBUTION = {\n package: REPORT_REMOTE_PACKAGE,\n face: 'host' as const,\n schemas: [],\n // This hand-written Remote has no generated reflection exports.\n model: { services: [], events: [], objects: [] },\n invocations: INVOCATION_DESCRIPTORS,\n}\n\nexport const REPORT_REMOTE_CONTRIBUTION: TypertRemoteContribution = {\n package: REPORT_REMOTE_PACKAGE,\n descriptors: INVOCATION_DESCRIPTORS,\n}\n","import type { DeviceScope } from '../device-auth.ts'\nimport type { DeepPilotReport, PairingGrantSnapshot, PushTestResult, RelayTestResult } from '../report-wire.ts'\nimport { REPORT_REMOTE_CONTRIBUTION } from '../report-wire.ts'\n\nexport type RemoteResult<T> =\n | { ok: true; value: T }\n | { ok: false; error: { message?: string } }\n\nexport interface ReportRemote {\n report(): Promise<RemoteResult<DeepPilotReport>>\n beginPairing(): Promise<RemoteResult<PairingGrantSnapshot>>\n revokeDevice(deviceId: string): Promise<RemoteResult<boolean>>\n /** Optional so a newer client can degrade against an older host. */\n setDeviceName?(deviceId: string, customName: string | null): Promise<RemoteResult<string | null>>\n setDeviceScopes(deviceId: string, scopes: DeviceScope[]): Promise<RemoteResult<DeviceScope[]>>\n /** Optional so an older host never breaks a newer client (and vice versa). */\n testRelay?(): Promise<RemoteResult<RelayTestResult>>\n /** Forces one real push delivery to every registered device. */\n testPush?(): Promise<RemoteResult<PushTestResult>>\n}\n\nexport interface ClientRemoteLike {\n $mount(contribution: unknown): Promise<() => Promise<void>>\n}\n\nexport interface MountedReportRemote {\n namespace: ReportRemote\n dispose: () => Promise<void>\n}\n\n/** Mount the contribution and resolve the namespace service it installs. */\nexport async function mountReportRemote(\n remote: ClientRemoteLike,\n resolveNamespace: () => ReportRemote | undefined,\n): Promise<MountedReportRemote> {\n const dispose = await remote.$mount(REPORT_REMOTE_CONTRIBUTION)\n const namespace = resolveNamespace()\n if (namespace === undefined) {\n await dispose()\n throw new Error('remote.deeppilot 未注册')\n }\n return { namespace, dispose }\n}\n","/**\n * Internationalization for the DeepPilot settings page.\n *\n * Architecture:\n * - The DSH host shell (via dsh-client-locale) owns language switching and\n * owns the locale face every client module can register against. When\n * that face is present we forward our strings to it and look them up via\n * `ctx.locale.bind(namespace)(key)`, which is the runtime's contract.\n * - When the locale face is absent (offline build, headless test, a\n * profile that doesn't include dsh-client-locale) we still need to\n * render the page in the user's language, so the same module ships a\n * built-in fallback table keyed identically and resolves keys locally.\n * - The `t(ctx, key, vars?)` helper hides which path is in use; callers\n * always go through it. The optional second argument performs\n * `{name}`-style substitution that the host bind() does not do.\n *\n * The tables below are the source of truth; the section header comment\n * here is the place to look when adding a key. A test in\n * `tests/i18n.test.ts` walks the table to guarantee every key in zh has a\n * matching en entry and vice versa, so a partial translation trips CI.\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\n\n/** DSH runtime locale face — structural, not imported (the package is not\n * on this plugin's dependency surface). */\ninterface LocaleFace {\n register: (namespace: string, table: unknown) => () => void\n bind: (namespace: string) => (key: string, vars?: Readonly<Record<string, unknown>>) => string\n getSnapshot?: () => { active: string; revision: number }\n}\n\ninterface AnyCtx extends Context {\n locale?: LocaleFace\n}\n\n/** Single namespace shared with the host's locale registry, so other\n * host-side modules (if any) can translate the same keys. */\nexport const DEEPPILOT_LOCALE_NS = 'settings.deeppilot'\n\n/** Locale codes this module currently ships. Keep in sync with the\n * language switches the host exposes; the fallback picks `en` if a user\n * ever requests a locale we don't translate. */\nexport type SupportedLocale = 'zh' | 'en'\n\n/** Translation function injected by a locale-aware slot. */\nexport type Translate = (key: string, vars?: Readonly<Record<string, unknown>>) => string\n\ninterface LocaleTables {\n zh: Record<string, string>\n en: Record<string, string>\n}\n\n/**\n * Single source of truth. Every key here MUST have a translation in every\n * supported locale; the i18n.test.ts \"table parity\" check enforces that.\n *\n * Shape: `{ locale: { key: value } }` — the same shape `dsh-client-locale`'s\n * `register(namespace, table)` accepts (and the same shape we already used\n * at the bottom of client/index.ts before this module existed).\n *\n * Naming convention: `<section>.<field>` (two dotted segments, lowercase,\n * ASCII-only). Names longer than two segments are reserved for future\n * sub-section splits and intentionally absent today.\n */\nconst TABLES: LocaleTables = {\n zh: {\n\n // 紧凑设置页:默认仅展示连接、设备与两个工具折叠行。\n 'local.options': '局域网连接选项',\n 'remote.options': '远程连接选项',\n 'local.errorDetails': '局域网连接异常,请检查连接选项({message})。',\n 'remote.errorDetails': '远程连接异常,请检查授权与连接选项({message})。',\n 'pair.add': '添加手机',\n 'pair.close': '收起',\n 'devices.count': '{count} 台',\n 'devices.moreAria': '设备“{name}”的更多操作',\n 'tools.title': '工具与信息',\n 'diag.reportFailed': '读取连接状态失败',\n 'diagnostics.historyCount': '{count} 条历史失败记录',\n 'diagnostics.kind.upgrade': '连接请求被拒绝',\n 'diagnostics.kind.pair': '配对请求被拒绝',\n 'diagnostics.kind.auth': '设备认证失败',\n 'diagnostics.kind.opened': '连接已建立',\n 'diagnostics.kind.closed': '连接异常断开',\n 'diagnostics.kind.error': '连接发生错误',\n 'diagnostics.kind.identity': '设备身份异常',\n 'diagnostics.kind.storage': '设备信息保存失败',\n 'diagnostics.kind.unknown': '连接异常',\n 'push.outcome.sent': '已发送',\n 'push.outcome.failed': '发送失败',\n 'push.outcome.invalid': '设备推送凭据无效',\n 'push.environment.development': '开发环境',\n 'push.environment.production': '正式环境',\n 'push.environment.other': '其他环境({environment})',\n 'push.outcome.other': '推送状态({outcome})',\n 'push.resultDetail': '推送结果({message})',\n\n // ---- meta / nav ----\n 'nav': 'DeepPilot',\n 'meta.title': 'DeepPilot',\n 'meta.intro': '在手机上使用这台电脑的 DSH。',\n 'meta.refresh': '刷新',\n\n // ---- master switch ----\n 'master.title': '允许手机连接',\n 'master.loading': '正在读取配置…',\n 'master.on': '已开启:接受手机连接。',\n 'master.off': '已关闭:不接受手机连接。',\n\n // ---- compact page hierarchy ----\n 'status.loading': '正在读取状态…',\n 'status.off': '未启用',\n 'status.ready': '服务已就绪',\n 'status.attention': '需要处理',\n 'connection.title': '连接',\n 'connection.description': '控制手机可用的局域网与公网连接。',\n 'connection.optionsSummary': '连接选项',\n 'pair.description': '选择连接方式并生成一次性配对信息。',\n 'devices.description': '管理已经配对的 iPhone。',\n 'troubleshooting.summary': '诊断工具',\n 'troubleshooting.title': '诊断工具',\n 'troubleshooting.description': '仅在排查连接或推送问题时使用。',\n 'troubleshooting.debugTitle': '调试日志',\n 'troubleshooting.debugDescription': '开启后,新的手机连接会在 DSH 终端输出诊断日志;已连接手机需重连后生效。日志不包含配对码、推送凭据或消息内容。',\n // ---- 连接诊断(P0:最近失败可观测) ----\n 'diagnostics.title': '连接诊断',\n 'diagnostics.description': '最近的连接失败事件;可一键复制后发给维护者排查。',\n 'diagnostics.recent': '最近失败',\n 'diagnostics.empty': '最近没有失败记录',\n 'diagnostics.staleHost': '宿主插件版本较旧,没有连接诊断数据,请更新 dsh-deeppilot。',\n 'diagnostics.copy': '复制诊断信息',\n 'diagnostics.copied': '诊断信息已复制',\n 'diagnostics.copyFailed': '复制诊断信息失败:',\n 'diagnostics.item': '{time} · {kind} · {reason}',\n 'diagnostics.attempt': '尝试 {id}',\n 'diagnostics.source': '来源 {label}',\n 'diagnostics.closeCode': '关闭码 {code}',\n 'diagnostics.duration': '耗时 {ms}ms',\n 'diagnostics.startedAt': '启动于 {time}',\n 'diagnostics.reportTitle': 'DeepPilot 诊断信息',\n 'diagnostics.reportGeneratedAt': '生成时间',\n 'diagnostics.reportVersion': '插件版本',\n 'diagnostics.reportEnabled': '总开关',\n 'diagnostics.reportLocal': '局域网',\n 'diagnostics.reportRemote': '公网',\n 'diagnostics.reportConnections': '当前连接',\n 'diagnostics.reportFailureHeader': '最近失败',\n 'diagnostics.reportNone': '(无)',\n 'diagnostics.on': '已启用',\n 'diagnostics.off': '已关闭',\n 'system.summary': '系统信息',\n 'system.title': '运行信息',\n 'system.description': '插件、协议与连接端点的技术信息。',\n\n // ---- local connection ----\n 'local.title': '局域网连接',\n 'local.autoRoute': '局域网连接始终开启:手机和电脑在同一 Wi-Fi 下会自动走局域网,在外面自动改走公网。',\n 'local.on': '已开启:手机可通过独立端口 {port} 以 TLS 加密连接。',\n 'local.off': '已关闭:不接受局域网连接。',\n 'local.tlsFingerprint': '证书指纹',\n 'local.tlsRegenerated': '局域网 TLS 身份已重新生成:此前通过内网配对的设备需要重新扫码配对。',\n 'local.phaseDisabled': '局域网连接未启用',\n 'local.phaseStarting': '局域网连接正在启动',\n 'local.phaseOnline': '局域网连接已就绪',\n 'local.phaseError': '局域网连接失败',\n 'local.phaseStopped': '局域网连接已停止',\n 'local.portTitle': '局域网端口',\n 'local.portDescription': '默认 3098,范围 1024–65535。该端口只以 TLS 提供 DeepPilot 的三个连接端点,不会开放完整 DSH。',\n 'local.portApplied': '局域网端口已保存,监听器正在重新加载。',\n 'local.portInvalid': '请输入 1024–65535 之间的整数。',\n 'local.portFailed': '局域网端口保存失败:',\n\n // ---- remote switch (Tailscale Funnel) ----\n 'remote.title': '远程连接',\n 'remote.on': '已配置:内嵌 Funnel 会自动启动并同步状态。',\n 'remote.off': '关闭:仅保留局域网连接。',\n 'remote.openAuth': '打开授权页面',\n 'remote.advancedSettings': '高级设置',\n 'remote.limitTitle': '每个公网来源的连接上限',\n 'remote.limitDescription': '默认 8,范围 1–16。应用后 Funnel 会重启,已有远程连接将短暂重连。',\n 'remote.limitApply': '应用',\n 'remote.limitApplied': '连接上限已保存,远程入口正在重新加载。',\n 'remote.limitInvalid': '请输入 1–16 之间的整数。',\n 'remote.limitFailed': '连接上限保存失败:',\n\n // ---- remote phases ----\n 'phase.disabled': '未启用',\n 'phase.starting': '正在启动',\n 'phase.login_required': '等待 Tailscale 授权',\n 'phase.online': '远程连接已就绪',\n 'phase.error': '远程连接失败',\n 'phase.unavailable': '远程 helper 不可用',\n 'phase.stopped': '已停止',\n 'phase.unknown': '状态未知',\n\n // ---- short channel states shown beside each switch ----\n 'channel.state.disabled': '未启用',\n 'channel.state.starting': '正在启动',\n 'channel.state.login_required': '待授权',\n 'channel.state.online': '已就绪',\n 'channel.state.error': '失败',\n 'channel.state.unavailable': '不可用',\n 'channel.state.stopped': '已停止',\n\n // ---- connection panel ----\n 'panel.activeConnections': '当前连接',\n 'panel.identity': '设备身份认证',\n 'panel.identityReady': 'v2 已就绪',\n 'panel.identityNotReady': '不可用',\n 'panel.token': '配对 Token',\n 'panel.tokenReady': '已就绪',\n 'panel.tokenNotReady': '未生成',\n 'panel.tokenMasked': '••••••••••••',\n 'panel.tokenAction.show': '显示',\n 'panel.tokenAction.hide': '隐藏',\n 'panel.tokenAction.copy': '复制',\n 'panel.tokenAction.rotate': '更换',\n 'panel.tokenAction.rotateConfirm': '确认更换?',\n 'panel.tokenAction.showing': '读取中…',\n 'panel.tokenAction.rotating': '更换中…',\n 'panel.tokenAutoHidden': 'Token 已自动隐藏',\n 'panel.tokenCopied': '已复制到剪贴板',\n 'panel.tokenCopyFailed': '复制失败:',\n 'panel.tokenRevealFailed': 'Token 读取失败:',\n 'panel.tokenRotateWarning': '更换会使当前 Token 立即失效、断开所有手机连接;5 秒内再次点击确认。',\n 'panel.tokenRotated': '新 Token 已生效,旧 Token 已失效;请重新配对所有设备。',\n 'panel.tokenRotateFailed': '更换失败:',\n\n // ---- pairing QR ----\n 'pair.qrPanelTitle': '添加手机',\n 'pair.kind.public': '公网',\n 'pair.kind.lan': '内网',\n 'pair.noAddress': '没有可用地址',\n 'pair.noAddressHelp': '没有可用的局域网或远程入口。请确认局域网连接已启动,或启用远程连接。',\n 'pair.disabledHelp': '请先开启“允许手机连接”,再添加手机。',\n 'pair.qrAlt': 'DeepPilot 配对二维码',\n 'pair.qrShow': '显示二维码',\n 'pair.qrHide': '隐藏二维码',\n 'pair.qrGenerating': '生成中…',\n 'pair.qrExpired': '配对码已过期,请重新显示二维码',\n 'pair.qrFailed': '二维码生成失败:',\n 'pair.qrRetry': '重试',\n 'pair.infoLabel': '配对信息(复制一次,粘贴到 App 即可)',\n 'pair.infoCopyDone': '配对信息已复制',\n 'pair.infoCopyFailed': '配对信息复制失败:',\n // `{kind}`: public | lan\n 'pair.qrHint': '二维码与「配对信息」内容相同:包含{kind}地址、一次性配对码、证书指纹(内网时)与主机标识。在局域网与公网之间切换会立即生成对应的新配对信息,配对码 5 分钟后失效。',\n\n // ---- advanced info ----\n 'advanced.summary': '高级信息',\n 'advanced.protocolVersion': '协议版本',\n 'advanced.serverVersion': '服务器版本',\n // 内嵌 Funnel helper 自报的 tailscale.com 版本;未上报时显示未获取。\n 'advanced.tailscaleVersion': 'Tailscale 版本',\n 'advanced.tailscaleVersionUnknown': '未获取',\n 'advanced.tokenPath': 'Token 路径',\n 'advanced.identityPath': '设备注册表路径',\n 'advanced.bufferMax': '重放缓冲上限',\n 'advanced.frames': ' 帧',\n\n // ---- push tests ----\n 'push.relayTitle': '离线推送中继',\n 'push.testRelay': '测试访问与注册',\n 'push.testPush': '发送测试通知',\n 'push.relayTesting': '测试中…',\n 'push.pushSending': '发送中…',\n 'push.relayDefault': '验证这台电脑到推送中继的连通性与自动注册是否正常。',\n 'push.pushDefault': '向所有已注册设备强制发送一条真实推送(不受在线状态与分类开关影响)。',\n 'push.relayOk': '通过',\n 'push.relayBad': '存在问题',\n 'push.relayUrlEmpty': '(未启用)',\n 'push.pushSent': '已送达',\n 'push.pushFailed': '发送失败',\n 'push.pushNoTargets': '无已注册设备',\n 'push.pushNotEnabled': '推送未启用',\n 'push.relayStep.health': '服务可达',\n 'push.relayStep.enroll': '自动注册',\n 'push.prefix.ok': '通过:',\n 'push.prefix.fail': '未通过:',\n\n // ---- devices table ----\n 'devices.title': '已配对设备',\n 'devices.col.name': '设备',\n 'devices.col.appVersion': 'App 版本',\n 'devices.col.push': '离线推送',\n 'devices.col.lastSeen': '最近在线',\n 'devices.col.fingerprint': '密钥指纹',\n 'devices.col.actions': '操作',\n 'devices.rename': '重命名',\n 'devices.renameAria': '重命名设备“{name}”',\n 'devices.nameLabel': '设备名称',\n 'devices.namePlaceholder': '例如:工作手机',\n 'devices.nameSave': '保存',\n 'devices.nameCancel': '取消',\n 'devices.nameSaving': '保存中…',\n 'devices.nameInvalid': '设备名称不能超过 64 个字符。',\n 'devices.customBadge': '自定义',\n 'devices.unnamed': '未命名设备',\n 'devices.renamed': '设备名称已保存',\n 'devices.nameCleared': '已恢复设备默认名称',\n 'devices.renameFailed': '设备名称保存失败:',\n 'devices.renameStaleHost': '宿主插件版本较旧,不支持设备重命名 — 请更新 dsh-deeppilot',\n 'devices.revoke': '删除',\n 'devices.revokeAria': '删除设备“{name}”',\n 'devices.deleting': '删除中…',\n 'devices.revokeConfirm': '确定删除设备“{name}”吗?该设备会立即断开,再次使用时需要重新配对。',\n 'devices.revoked': '设备已删除',\n 'devices.revokeFailed': '设备删除失败:',\n 'devices.pushRegistered': '已注册(',\n 'devices.pushNotRegistered': '未注册',\n 'devices.pushEnvProduction': '生产',\n 'devices.pushEnvDevelopment': '开发',\n 'devices.empty': '还没有配对设备。点击“添加手机”,然后在 DeepPilot 中扫码连接。',\n\n // ---- remote help ----\n 'help.remoteTitle': '远程连接帮助',\n 'help.recommended': '推荐设置流程',\n 'help.step1': '先打开“允许手机连接”,再打开“远程连接”。',\n 'help.step2': '状态变为\"等待 Tailscale 授权\"后,点击\"打开授权页面\"。',\n 'help.step3': '使用有权管理此 Tailnet 的账号登录,并按授权页提示启用 Funnel。通常需要 Owner、Admin 或 Network admin 权限。',\n 'help.step4': '返回此页面并点击“刷新”。远程连接显示“已就绪”后,点击“添加手机”并扫码。',\n 'help.funnelHint': '插件已内嵌 Tailscale 网络组件,这台电脑和手机都不需要另外安装 Tailscale App;但首次启用仍需由 Tailnet 管理员授权。',\n 'help.httpsTitle': '授权页未自动完成时:开启 HTTPS',\n 'help.httpsStep1': '打开 Tailscale 管理后台的 Network → DNS。',\n 'help.httpsStep2': '确认 MagicDNS 已开启。',\n 'help.httpsStep3': '在 HTTPS Certificates 中点击 Enable HTTPS。',\n 'help.httpsHint': '启用 HTTPS 后,设备的完整域名会写入公开的证书透明度日志。如果设备名包含敏感信息,请先在 Tailscale 中重命名设备。',\n 'help.allowTitle': '授权页未自动完成时:允许 Funnel',\n 'help.allowBody': '打开 Access controls → Definitions,选择 Node attributes。在现有 nodeAttrs 数组中追加下面这一项;不要覆盖已有访问规则,也不要创建第二个 nodeAttrs 顶层字段。',\n 'help.allowHint': '保存策略后回到本页刷新。公共 DNS 和权限变更可能需要几分钟生效。',\n 'help.faqTitle': '常见问题',\n 'help.faq1': '提示\"HTTPS must be enabled\":完成上面的 HTTPS Certificates 设置。',\n 'help.faq2': '\"Funnel not available\":确认 nodeAttrs 已保存,并且当前节点属于规则的 target。',\n 'help.faq3': '已有公网地址但手机超时:等待几分钟后重试,同时确认这台电脑未休眠、DSH 正在运行,再重新扫描最新二维码。',\n 'help.faq4': '没有公网地址:检查 Tailscale 授权是否完成,然后点击\"刷新\"或重启 DSH。',\n 'help.securityTitle': '安全说明',\n 'help.security1': 'Funnel 公网地址可从互联网访问,但连接必须使用已配对设备的 P-256 私钥签名;不要分享仍在有效期内的配对二维码。',\n 'help.security2': '丢失设备时可在设备列表中单独删除;该设备会立即断开,不影响其他手机。',\n 'help.security3': 'Funnel 和局域网监听器都只提供 /phone、/phone/pair 和 /phone/health,不会暴露完整 DSH Web/API。',\n 'help.security4': '局域网连接使用插件独立的 3098 端口并启用 TLS。只在可信网络中使用,不要把该端口转发到公网。',\n 'help.security5': '关闭远程连接开关会停止 Funnel,但不会影响可用的局域网连接。',\n 'help.funnelDocs': 'Tailscale Funnel 官方文档',\n 'help.docsPrefix': '更多信息:',\n\n // ---- diagnostic line (visible when something is missing) ----\n 'diag.summary': '技术诊断',\n 'diag.remoteUnavailable': 'remote 服务不可用',\n 'diag.remoteUnmounted': 'report remote 未挂载',\n 'diag.mountFailed': '报告远程未挂载(remote mount 失败)— 请确认宿主包含 typert 组合',\n 'diag.mountFailedShort': 'remote mount 失败: ',\n 'diag.callFailed': 'report remote 调用失败',\n 'diag.settingsUnavailable': '设置表单不可用(configForms 未提供)',\n 'diag.missingReportHook': 'useDeepPilotReport hook 缺失',\n 'diag.missingEnabledHook': 'useDeepPilotEnabled hook 缺失',\n 'diag.missingLocalPortHook': 'useDeepPilotLocalPort hook 缺失',\n 'diag.missingRemoteEnabledHook': 'useDeepPilotRemoteEnabled hook 缺失',\n 'diag.missingRemoteLimitHook': 'useDeepPilotRemoteConnectionLimit hook 缺失',\n 'diag.missingDebugHook': 'useDeepPilotDebug hook 缺失',\n 'diag.missingRefresh': 'refresh 回调缺失',\n 'diag.missingReveal': 'beginPairing 回调缺失',\n 'diag.missingRotate': 'revokeDevice 回调缺失',\n 'diag.missingRename': 'setDeviceName 回调缺失',\n 'diag.missingTestRelay': 'testRelay 回调缺失',\n 'diag.missingTestPush': 'testPush 回调缺失',\n 'diag.missingSetEnabled': 'setDeepPilotEnabled 回调缺失',\n 'diag.missingSetLocalPort': 'setDeepPilotLocalPort 回调缺失',\n 'diag.missingSetRemote': 'setDeepPilotRemoteEnabled 回调缺失',\n 'diag.missingSetRemoteLimit': 'setDeepPilotRemoteConnectionLimit 回调缺失',\n 'diag.missingSetDebug': 'setDeepPilotDebug 回调缺失',\n 'diag.renderError': '渲染异常: ',\n 'diag.prefix': 'diag: ',\n\n // ---- clipboard fallback error (unrelated to user action) ----\n 'clipboard.rejected': '浏览器拒绝了剪贴板写入',\n\n // ---- push test edge cases (server-side messages the UI surfaces verbatim) ----\n 'push.staleHost': '宿主插件版本较旧,不支持推送测试',\n 'push.staleHostRelay': '宿主插件版本较旧,不支持中继测试',\n 'push.staleHostPush': '宿主插件版本较旧,不支持推送测试 — 请更新 dsh-deeppilot',\n 'push.staleHostPushRelay': '宿主插件版本较旧,不支持中继测试 — 请更新 dsh-deeppilot',\n\n // ---- update checker ----\n 'update.badge': '有新版本',\n },\n\n en: {\n\n // Compact settings surface.\n 'local.options': 'LAN connection options',\n 'remote.options': 'Remote connection options',\n 'local.errorDetails': 'LAN connection failed. Check the connection options ({message}).',\n 'remote.errorDetails': 'Remote connection failed. Check authorization and connection options ({message}).',\n 'pair.add': 'Add phone',\n 'pair.close': 'Collapse',\n 'devices.count': '{count} devices',\n 'devices.moreAria': 'More actions for “{name}”',\n 'tools.title': 'Tools and information',\n 'diag.reportFailed': 'Failed to read connection status',\n 'diagnostics.historyCount': '{count} past failures',\n 'diagnostics.kind.upgrade': 'Connection request rejected',\n 'diagnostics.kind.pair': 'Pairing request rejected',\n 'diagnostics.kind.auth': 'Device authentication failed',\n 'diagnostics.kind.opened': 'Connection opened',\n 'diagnostics.kind.closed': 'Connection closed unexpectedly',\n 'diagnostics.kind.error': 'Connection error',\n 'diagnostics.kind.identity': 'Device identity error',\n 'diagnostics.kind.storage': 'Saving device information failed',\n 'diagnostics.kind.unknown': 'Connection problem',\n 'push.outcome.sent': 'Sent',\n 'push.outcome.failed': 'Failed to send',\n 'push.outcome.invalid': 'Invalid push credentials',\n 'push.environment.development': 'Development',\n 'push.environment.production': 'Production',\n 'push.environment.other': 'Other environment ({environment})',\n 'push.outcome.other': 'Push status ({outcome})',\n 'push.resultDetail': 'Push result ({message})',\n\n // ---- meta / nav ----\n 'nav': 'DeepPilot',\n 'meta.title': 'DeepPilot',\n 'meta.intro': 'Use this computer’s DSH from your phone.',\n 'meta.refresh': 'Refresh',\n\n // ---- master switch ----\n 'master.title': 'Allow phone connections',\n 'master.loading': 'Loading settings…',\n 'master.on': 'On: accepting phone connections.',\n 'master.off': 'Off: not accepting phone connections.',\n\n // ---- compact page hierarchy ----\n 'status.loading': 'Loading status…',\n 'status.off': 'Disabled',\n 'status.ready': 'Service ready',\n 'status.attention': 'Needs attention',\n 'connection.title': 'Connections',\n 'connection.description': 'Control the LAN and public connections available to your phone.',\n 'connection.optionsSummary': 'Connection options',\n 'pair.description': 'Choose a connection type and generate one-time pairing information.',\n 'devices.description': 'Manage iPhones that are already paired.',\n 'troubleshooting.summary': 'Diagnostic tools',\n 'troubleshooting.title': 'Diagnostic tools',\n 'troubleshooting.description': 'Use these only when diagnosing connection or push issues.',\n 'troubleshooting.debugTitle': 'Debug logging',\n 'troubleshooting.debugDescription': 'New phone connections write diagnostic logs to the DSH terminal. Connected phones must reconnect to pick up the change. Logs exclude pairing codes, push credentials, and message content.',\n // ---- connection diagnostics (P0: observable failures) ----\n 'diagnostics.title': 'Connection diagnostics',\n 'diagnostics.description': 'Recent connection failures; copy them for troubleshooting.',\n 'diagnostics.recent': 'Recent failures',\n 'diagnostics.empty': 'No recent failures',\n 'diagnostics.staleHost': 'This host is too old to report connection diagnostics. Update dsh-deeppilot.',\n 'diagnostics.copy': 'Copy diagnostics',\n 'diagnostics.copied': 'Diagnostics copied',\n 'diagnostics.copyFailed': 'Copying diagnostics failed: ',\n 'diagnostics.item': '{time} · {kind} · {reason}',\n 'diagnostics.attempt': 'attempt {id}',\n 'diagnostics.source': 'source {label}',\n 'diagnostics.closeCode': 'close code {code}',\n 'diagnostics.duration': '{ms}ms',\n 'diagnostics.startedAt': 'Started {time}',\n 'diagnostics.reportTitle': 'DeepPilot diagnostics',\n 'diagnostics.reportGeneratedAt': 'Generated',\n 'diagnostics.reportVersion': 'Plugin version',\n 'diagnostics.reportEnabled': 'Master switch',\n 'diagnostics.reportLocal': 'LAN',\n 'diagnostics.reportRemote': 'Funnel',\n 'diagnostics.reportConnections': 'Active connections',\n 'diagnostics.reportFailureHeader': 'Recent failures',\n 'diagnostics.reportNone': '(none)',\n 'diagnostics.on': 'enabled',\n 'diagnostics.off': 'disabled',\n 'system.summary': 'System information',\n 'system.title': 'Runtime information',\n 'system.description': 'Technical details about the plugin, protocol, and endpoints.',\n\n // ---- local connection ----\n 'local.title': 'LAN connection',\n 'local.autoRoute': 'LAN connections are always on: on the same Wi-Fi the phone connects over the LAN automatically, and switches to the public route when away.',\n 'local.on': 'On: phones connect over TLS through the independent port {port}.',\n 'local.off': 'Off: LAN connections are not accepted.',\n 'local.tlsFingerprint': 'Certificate fingerprint',\n 'local.tlsRegenerated': 'The LAN TLS identity was regenerated: devices previously paired over LAN must scan a new pairing QR.',\n 'local.phaseDisabled': 'LAN connection disabled',\n 'local.phaseStarting': 'LAN connection starting',\n 'local.phaseOnline': 'LAN connection ready',\n 'local.phaseError': 'LAN connection failed',\n 'local.phaseStopped': 'LAN connection stopped',\n 'local.portTitle': 'LAN port',\n 'local.portDescription': 'Default 3098; range 1024–65535. This port serves only the three DeepPilot endpoints over TLS, never the full DSH server.',\n 'local.portApplied': 'LAN port saved; the listener is reloading.',\n 'local.portInvalid': 'Enter an integer from 1024 to 65535.',\n 'local.portFailed': 'Failed to save LAN port: ',\n\n // ---- remote switch (Tailscale Funnel) ----\n 'remote.title': 'Remote connection',\n 'remote.on': 'Configured: the embedded Funnel will start and sync state automatically.',\n 'remote.off': 'Off: LAN connections only.',\n 'remote.openAuth': 'Open authorization page',\n 'remote.advancedSettings': 'Advanced settings',\n 'remote.limitTitle': 'Connections per public source',\n 'remote.limitDescription': 'Default 8; range 1–16. Applying restarts Funnel and briefly reconnects existing remote clients.',\n 'remote.limitApply': 'Apply',\n 'remote.limitApplied': 'Connection limit saved; the remote endpoint is reloading.',\n 'remote.limitInvalid': 'Enter an integer from 1 to 16.',\n 'remote.limitFailed': 'Failed to save connection limit: ',\n\n // ---- remote phases ----\n 'phase.disabled': 'Disabled',\n 'phase.starting': 'Starting',\n 'phase.login_required': 'Awaiting Tailscale authorization',\n 'phase.online': 'Remote connection ready',\n 'phase.error': 'Remote connection failed',\n 'phase.unavailable': 'Remote helper unavailable',\n 'phase.stopped': 'Stopped',\n 'phase.unknown': 'Status unknown',\n\n // ---- short channel states shown beside each switch ----\n 'channel.state.disabled': 'Off',\n 'channel.state.starting': 'Starting',\n 'channel.state.login_required': 'Needs sign-in',\n 'channel.state.online': 'Ready',\n 'channel.state.error': 'Failed',\n 'channel.state.unavailable': 'Unavailable',\n 'channel.state.stopped': 'Stopped',\n\n // ---- connection panel ----\n 'panel.activeConnections': 'Active connections',\n 'panel.identity': 'Device authentication',\n 'panel.identityReady': 'v2 ready',\n 'panel.identityNotReady': 'Unavailable',\n 'panel.token': 'Pairing token',\n 'panel.tokenReady': 'Ready',\n 'panel.tokenNotReady': 'Not generated',\n 'panel.tokenMasked': '••••••••••••',\n 'panel.tokenAction.show': 'Show',\n 'panel.tokenAction.hide': 'Hide',\n 'panel.tokenAction.copy': 'Copy',\n 'panel.tokenAction.rotate': 'Rotate',\n 'panel.tokenAction.rotateConfirm': 'Confirm rotate?',\n 'panel.tokenAction.showing': 'Reading…',\n 'panel.tokenAction.rotating': 'Rotating…',\n 'panel.tokenAutoHidden': 'Token auto-hidden',\n 'panel.tokenCopied': 'Copied to clipboard',\n 'panel.tokenCopyFailed': 'Copy failed: ',\n 'panel.tokenRevealFailed': 'Token reveal failed: ',\n 'panel.tokenRotateWarning': 'Rotation invalidates the current token immediately and drops every paired phone. Click again within 5s to confirm.',\n 'panel.tokenRotated': 'New token active, old token invalidated. Please re-pair every device.',\n 'panel.tokenRotateFailed': 'Rotation failed: ',\n\n // ---- pairing QR ----\n 'pair.qrPanelTitle': 'Add phone',\n 'pair.kind.public': 'Public',\n 'pair.kind.lan': 'LAN',\n 'pair.noAddress': 'No address available',\n 'pair.noAddressHelp': 'No LAN or remote endpoint is available. Make sure LAN is running or enable remote access.',\n 'pair.disabledHelp': 'Turn on “Allow phone connections” before adding a phone.',\n 'pair.qrAlt': 'DeepPilot pairing QR code',\n 'pair.qrShow': 'Show QR code',\n 'pair.qrHide': 'Hide QR code',\n 'pair.qrGenerating': 'Generating…',\n 'pair.qrExpired': 'Pairing code expired — show the QR code again',\n 'pair.qrFailed': 'QR generation failed: ',\n 'pair.qrRetry': 'Retry',\n 'pair.infoLabel': 'Pairing info (copy once, paste it in the app)',\n 'pair.infoCopyDone': 'Pairing info copied',\n 'pair.infoCopyFailed': 'Failed to copy pairing info: ',\n 'pair.qrHint': 'The QR code and the pairing info carry the same {kind} address, single-use code, certificate fingerprint (for LAN) and host identity. Switching between LAN and public issues a matching new string immediately; the code expires after 5 minutes.',\n\n // ---- advanced info ----\n 'advanced.summary': 'Advanced info',\n 'advanced.protocolVersion': 'Protocol version',\n 'advanced.serverVersion': 'Server version',\n 'advanced.tailscaleVersion': 'Tailscale version',\n 'advanced.tailscaleVersionUnknown': 'Not reported',\n 'advanced.tokenPath': 'Token path',\n 'advanced.identityPath': 'Device registry path',\n 'advanced.bufferMax': 'Replay buffer cap',\n 'advanced.frames': ' frames',\n\n // ---- push tests ----\n 'push.relayTitle': 'Offline push relay',\n 'push.testRelay': 'Test reach & enroll',\n 'push.testPush': 'Send test notification',\n 'push.relayTesting': 'Testing…',\n 'push.pushSending': 'Sending…',\n 'push.relayDefault': 'Verify this computer → push relay connectivity and zero-touch enrollment.',\n 'push.pushDefault': 'Force one real push to every registered device (ignores online state and category switches).',\n 'push.relayOk': 'OK',\n 'push.relayBad': 'Issues found',\n 'push.relayUrlEmpty': '(disabled)',\n 'push.pushSent': 'Delivered',\n 'push.pushFailed': 'Send failed',\n 'push.pushNoTargets': 'No registered devices',\n 'push.pushNotEnabled': 'Push not enabled',\n 'push.relayStep.health': 'Service reachable',\n 'push.relayStep.enroll': 'Auto enrollment',\n 'push.prefix.ok': 'Passed: ',\n 'push.prefix.fail': 'Failed: ',\n\n // ---- devices table ----\n 'devices.title': 'Paired devices',\n 'devices.col.name': 'Device',\n 'devices.col.appVersion': 'App version',\n 'devices.col.push': 'Push',\n 'devices.col.lastSeen': 'Last seen',\n 'devices.col.fingerprint': 'Key fingerprint',\n 'devices.col.actions': 'Actions',\n 'devices.rename': 'Rename',\n 'devices.renameAria': 'Rename device “{name}”',\n 'devices.nameLabel': 'Device name',\n 'devices.namePlaceholder': 'For example: Work phone',\n 'devices.nameSave': 'Save',\n 'devices.nameCancel': 'Cancel',\n 'devices.nameSaving': 'Saving…',\n 'devices.nameInvalid': 'Device names cannot exceed 64 characters.',\n 'devices.customBadge': 'Custom',\n 'devices.unnamed': 'Unnamed device',\n 'devices.renamed': 'Device name saved',\n 'devices.nameCleared': 'Restored the device default name',\n 'devices.renameFailed': 'Failed to save device name: ',\n 'devices.renameStaleHost': 'The host plugin is too old to rename devices — please update dsh-deeppilot',\n 'devices.revoke': 'Delete',\n 'devices.revokeAria': 'Delete device “{name}”',\n 'devices.deleting': 'Deleting…',\n 'devices.revokeConfirm': 'Delete “{name}”? It will disconnect immediately and must pair again before reconnecting.',\n 'devices.revoked': 'Device deleted',\n 'devices.revokeFailed': 'Failed to delete device: ',\n 'devices.pushRegistered': 'Registered (',\n 'devices.pushNotRegistered': 'Not registered',\n 'devices.pushEnvProduction': 'Production',\n 'devices.pushEnvDevelopment': 'Development',\n 'devices.empty': 'No paired devices yet. Click “Add phone”, then scan the QR code in DeepPilot.',\n\n // ---- remote help ----\n 'help.remoteTitle': 'Remote connection help',\n 'help.recommended': 'Recommended setup',\n 'help.step1': 'Turn on “Allow phone connections”, then “Remote connection”.',\n 'help.step2': 'When the status shows \"Awaiting Tailscale authorization\", click \"Open authorization page\".',\n 'help.step3': 'Sign in with an account that can manage this Tailnet and follow the on-page prompts to enable Funnel. Owner / Admin / Network admin is usually required.',\n 'help.step4': 'Return and click “Refresh”. Once the remote connection is ready, click “Add phone” and scan the QR code.',\n 'help.funnelHint': 'The plugin bundles the Tailscale networking stack, so neither this computer nor the phone needs the Tailscale app — but a Tailnet administrator must approve first-time use.',\n 'help.httpsTitle': 'If authorization does not complete: enable HTTPS',\n 'help.httpsStep1': 'Open the Tailscale admin console → Network → DNS.',\n 'help.httpsStep2': 'Confirm MagicDNS is enabled.',\n 'help.httpsStep3': 'In HTTPS Certificates click Enable HTTPS.',\n 'help.httpsHint': 'Enabling HTTPS publishes the device hostname to public certificate transparency logs. Rename the device in Tailscale first if its name is sensitive.',\n 'help.allowTitle': 'If authorization does not complete: allow Funnel',\n 'help.allowBody': 'Open Access controls → Definitions, select Node attributes. Append the snippet below to your existing nodeAttrs array; do not overwrite other access rules and do not add a second top-level nodeAttrs field.',\n 'help.allowHint': 'Save the policy and refresh this page. Public DNS and policy changes can take a few minutes to propagate.',\n 'help.faqTitle': 'Frequently asked questions',\n 'help.faq1': '\"HTTPS must be enabled\" — finish the HTTPS Certificates steps above.',\n 'help.faq2': '\"Funnel not available\" — make sure the nodeAttrs snippet is saved and this node is in the rule\\'s target.',\n 'help.faq3': 'Public URL exists but the phone times out: wait a few minutes, confirm the computer is awake and DSH is running, then re-scan the latest QR code.',\n 'help.faq4': 'No public URL: check that Tailscale authorization completed, then click \"Refresh\" or restart DSH.',\n 'help.securityTitle': 'Security notes',\n 'help.security1': 'A Funnel URL is public, but every connection requires a signature from a paired device P-256 private key. Do not share a pairing QR while it is valid.',\n 'help.security2': 'If a device is lost, delete only that device from the list. It disconnects immediately; other phones stay paired.',\n 'help.security3': 'Funnel and the LAN listener expose only /phone, /phone/pair, and /phone/health, never the full DSH Web/API surface.',\n 'help.security4': 'LAN uses the plugin\\'s independent port 3098 with TLS enabled. Use trusted networks only and never forward that port to the public Internet.',\n 'help.security5': 'Disabling the remote switch stops Funnel but does not affect any LAN connection you already have.',\n 'help.funnelDocs': 'Tailscale Funnel docs',\n 'help.docsPrefix': 'More info: ',\n\n // ---- diagnostic line (visible when something is missing) ----\n 'diag.summary': 'Technical diagnostics',\n 'diag.remoteUnavailable': 'remote service unavailable',\n 'diag.remoteUnmounted': 'report remote not mounted',\n 'diag.mountFailed': 'Report remote not mounted (mount failed) — confirm the host includes the typert composition',\n 'diag.mountFailedShort': 'remote mount failed: ',\n 'diag.callFailed': 'report remote call failed',\n 'diag.settingsUnavailable': 'Settings form unavailable (configForms not provided)',\n 'diag.missingReportHook': 'useDeepPilotReport hook missing',\n 'diag.missingEnabledHook': 'useDeepPilotEnabled hook missing',\n 'diag.missingLocalPortHook': 'useDeepPilotLocalPort hook missing',\n 'diag.missingRemoteEnabledHook': 'useDeepPilotRemoteEnabled hook missing',\n 'diag.missingRemoteLimitHook': 'useDeepPilotRemoteConnectionLimit hook missing',\n 'diag.missingDebugHook': 'useDeepPilotDebug hook missing',\n 'diag.missingRefresh': 'refresh callback missing',\n 'diag.missingReveal': 'beginPairing callback missing',\n 'diag.missingRotate': 'revokeDevice callback missing',\n 'diag.missingRename': 'setDeviceName callback missing',\n 'diag.missingTestRelay': 'testRelay callback missing',\n 'diag.missingTestPush': 'testPush callback missing',\n 'diag.missingSetEnabled': 'setDeepPilotEnabled callback missing',\n 'diag.missingSetLocalPort': 'setDeepPilotLocalPort callback missing',\n 'diag.missingSetRemote': 'setDeepPilotRemoteEnabled callback missing',\n 'diag.missingSetRemoteLimit': 'setDeepPilotRemoteConnectionLimit callback missing',\n 'diag.missingSetDebug': 'setDeepPilotDebug callback missing',\n 'diag.renderError': 'Render error: ',\n 'diag.prefix': 'diag: ',\n\n // ---- clipboard fallback error (unrelated to user action) ----\n 'clipboard.rejected': 'Clipboard write rejected by the browser',\n\n // ---- push test edge cases (server-side messages the UI surfaces verbatim) ----\n 'push.staleHost': 'Host plugin is too old for push testing',\n 'push.staleHostRelay': 'Host plugin is too old for relay testing',\n 'push.staleHostPush': 'Host plugin is too old for push testing — please update dsh-deeppilot',\n 'push.staleHostPushRelay': 'Host plugin is too old for relay testing — please update dsh-deeppilot',\n\n // ---- update checker ----\n 'update.badge': 'New version available',\n },\n}\n\nconst ALL_KEYS: ReadonlyArray<string> = Object.keys(TABLES.zh)\n/** Throw-on-missing helper, used by tests and as a last-ditch fallback in\n * `t()`. Kept exported so the parity test can walk the entire namespace. */\nexport function translateOrThrow(\n locale: SupportedLocale,\n key: string,\n): string {\n const value = TABLES[locale][key]\n if (value === undefined) {\n throw new Error(`i18n: missing key \"${key}\" in ${locale} table`)\n }\n return value\n}\n\n/** Substitute every `{name}` in `template` with `String(vars[name])`. The\n * host bind() does not interpolate, so we always run the result through\n * here for any key the caller asked to format. Numeric / object placeholders\n * are coerced to strings; missing placeholders are left intact so a\n * missing key is visible in the rendered output. */\nexport function interpolate(\n template: string,\n vars?: Readonly<Record<string, unknown>>,\n): string {\n if (!vars) return template\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) => {\n const value = vars[name]\n if (value === undefined) return match\n return String(value)\n })\n}\n\n/** Detect the active language from the locale snapshot or browser hints. */\nfunction detectLocale(ctx: AnyCtx): SupportedLocale {\n try {\n const active = ctx.locale?.getSnapshot?.().active\n if (active === 'zh' || active?.toLowerCase().startsWith('zh-')) return 'zh'\n if (active === 'en' || active?.toLowerCase().startsWith('en-')) return 'en'\n } catch {\n // Fall through to browser hints when the locale face is unavailable.\n }\n\n const htmlLanguage = typeof document === 'undefined' ? '' : document.documentElement.lang\n if (htmlLanguage.toLowerCase().startsWith('zh')) return 'zh'\n const browserLanguages = typeof navigator === 'undefined' ? [] : navigator.languages\n if (browserLanguages.some((language) => language.toLowerCase().startsWith('zh'))) return 'zh'\n return 'en'\n}\n\n/**\n * Invoke the translation function supplied to a locale-aware slot. Keeping\n * this adapter distinct from `t(ctx, ...)` prevents a translator function\n * from being mistaken for a Cordis Context, which previously forced every\n * settings-page lookup through the English no-host fallback.\n */\nexport function translateWith(\n translator: unknown,\n key: string,\n vars?: Readonly<Record<string, unknown>>,\n): string {\n if (typeof translator !== 'function') return key\n return (translator as Translate)(key, vars)\n}\n\n/** Translation function. Callers always go through this — never the\n * underlying locale face — so the substitution / fallback path stays in\n * one place. `ctx` may be omitted (offline / SSR / tests) and we resolve\n * to en automatically. */\nexport function t(\n ctx: Context | undefined,\n key: string,\n vars?: Readonly<Record<string, unknown>>,\n): string {\n const anyCtx = ctx as AnyCtx | undefined\n let template: string | undefined\n // Prefer the host locale when it can answer; fall back to our table only\n // when the host does not know the key (e.g. unsupported language) or\n // there is no host at all. The bind contract is `string`, so a missing\n // key is signalled by throwing — catch and fall through.\n if (anyCtx?.locale) {\n try {\n template = anyCtx.locale.bind(DEEPPILOT_LOCALE_NS)(key)\n } catch {\n template = undefined\n }\n }\n if (template === undefined || template === key) {\n const locale = detectLocale(anyCtx ?? ({ locale: undefined } as unknown as AnyCtx))\n // Walk the local tables; the test for a missing key in our own zh/en\n // tables is a *bug* in this module and must not crash the page. We\n // surface the key itself so the gap is visible in the rendered\n // output rather than masked by a blank or an exception.\n template = TABLES[locale][key] ?? TABLES.zh[key] ?? TABLES.en[key] ?? key\n }\n return interpolate(template, vars)\n}\n\n/** Register both dictionaries and return the host-owned disposer. */\nexport function registerLocale(ctx: Context): () => void {\n const anyCtx = ctx as AnyCtx\n if (anyCtx.locale === undefined) return () => {}\n return anyCtx.locale.register(DEEPPILOT_LOCALE_NS, {\n zh: TABLES.zh,\n en: TABLES.en,\n })\n}\n\n/** Test-time access: read every key we ship. Used by the parity test to\n * guarantee zh and en stay in lock-step. */\nexport function _allKeysForTest(): ReadonlyArray<string> {\n return ALL_KEYS\n}\n","const CSS = String.raw`\n.pbb-section{--pbb-ink:var(--dsw-alias-label-primary,#0f1115);--pbb-secondary:var(--dsw-alias-label-secondary,#61666b);--pbb-line:var(--dsw-alias-settings-card-stroke,var(--dsw-alias-border-l3,#e4e5e7));--pbb-fill:var(--dsw-alias-settings-card-fill,var(--dsw-alias-bg-layer-2,#fff));--pbb-soft:var(--dsw-alias-bg-module-platform,#f5f6f8);container:pbb/inline-size;max-width:760px;color:var(--pbb-ink);font-size:14px;line-height:20px;display:flex;flex-direction:column;gap:20px}\n.pbb-section *{box-sizing:border-box}\n.pbb-section :is(.pbb-action,.pbb-refresh,.pbb-iconButton,.pbb-cardHead,.pbb-menuAction,.pbb-targetButton),.pbb-section input{font-family:inherit}\n.pbb-icon{display:block;flex:none;color:inherit}\n.pbb-pageHeader{display:flex;align-items:flex-start;gap:12px;min-height:56px}\n.pbb-pageHeader>div{min-width:0;flex:1;padding-top:2px}\n.pbb-title{margin:0;font-size:20px;line-height:27px;font-weight:600;letter-spacing:-.3px}\n.pbb-intro{color:var(--pbb-secondary);font-size:14px;line-height:20px;margin:5px 0 0}\n.pbb-refresh{display:inline-flex;align-items:center;justify-content:center;gap:5px;height:28px;padding:0 7px;flex:none;border:0;border-radius:6px;background:transparent;color:var(--pbb-secondary);font-size:12px;cursor:pointer}\n.pbb-card{border:1px solid var(--pbb-line);border-radius:18px;background:var(--pbb-fill)}\n.pbb-cardTitle{margin:0;font-size:14px;line-height:20px;font-weight:600;color:var(--pbb-ink)}\n.pbb-cardBody{display:flex;flex-direction:column;gap:12px;padding:4px 16px 16px}\n.pbb-connections>.pbb-cardBody{padding:0;gap:0}\n.pbb-row{display:flex;align-items:center;gap:8px;min-width:0}\n.pbb-masterRow{display:flex;align-items:center;gap:12px;min-height:66px;padding:11px 16px}\n.pbb-controlText{display:flex;flex:1;min-width:0;flex-direction:column;gap:2px}\n.pbb-masterRow>.pbb-controlText{gap:4px}\n.pbb-controlTitle{font-size:14px;line-height:20px;font-weight:400;color:var(--pbb-ink)}\n.pbb-masterRow .pbb-controlTitle{font-weight:600}\n.pbb-controlDescription,.pbb-diag,.pbb-label,.pbb-value{font-size:12px;line-height:18px;color:var(--pbb-secondary)}\n.pbb-serviceSummary,.pbb-channelState{display:flex;align-items:center;flex-wrap:wrap;gap:6px;font-size:12px;line-height:18px;color:var(--pbb-secondary)}\n.pbb-serviceSummary{gap:5px}\n.pbb-serviceState{display:inline-flex}\n.pbb-metaDivider{height:10px;border-left:1px solid var(--pbb-line);margin:0 2px}\n.pbb-channel{position:relative}\n.pbb-channel::before{content:\"\";position:absolute;top:0;left:16px;right:16px;border-top:1px solid var(--pbb-line)}\n.pbb-channel+.pbb-channel::before{left:46px}\n.pbb-channelRow{gap:12px;min-height:60px;padding:8px 16px}\n.pbb-channelRow>.pbb-icon{color:var(--pbb-secondary)}\n.pbb-channelBody{display:flex;flex-direction:column;gap:12px;padding:2px 16px 14px 46px}\n.pbb-channel>.pbb-diag,.pbb-channel>.pbb-rowAction{margin:0;padding:0 16px 8px 46px}\n.pbb-fold[hidden]{display:none}\n.pbb-action:disabled,.pbb-refresh:disabled,.pbb-menuAction:disabled,.pbb-targetButton:disabled{opacity:.5;cursor:default}\n.pbb-action{display:inline-flex;align-items:center;justify-content:center;gap:5px;flex:none;height:28px;max-width:100%;padding:0 9px;border:1px solid var(--pbb-line);border-radius:6px;background:transparent;color:var(--pbb-secondary);font:inherit;font-size:14px;line-height:20px;text-decoration:none;cursor:pointer;white-space:nowrap}\n.pbb-addAction{display:flex;margin-left:auto}\n.pbb-buttonPrimary{background:var(--dsw-alias-button-primary-fill,var(--pbb-ink));border-color:transparent;color:var(--dsw-alias-label-primary-foreground,#fff)}\n.pbb-actionDangerGhost{color:var(--dsw-alias-state-error-primary,#bc2222);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary,#bc2222) 35%,transparent)}\n.pbb-iconButton{display:flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;padding:0;border:0;border-radius:6px;background:transparent;color:var(--pbb-secondary);cursor:pointer}\n.pbb-chev{display:inline-flex;flex:none;color:var(--pbb-secondary)}\n.pbb-chevIcon{width:14px;height:14px;display:block}\n[aria-expanded=\"true\"]>.pbb-chev,.pbb-helpDisclosure[open]>summary>.pbb-chev,.pbb-disclosure[open]>summary>.pbb-chev{transform:rotate(90deg)}\n.pbb-diag{margin:0;overflow-wrap:anywhere}\n.pbb-diagBad,.pbb-bad{color:var(--dsw-alias-state-error-primary,#bc2222)}\n.pbb-ok{color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#287a45) 65%,var(--pbb-ink))}\n.pbb-label{flex:1;min-width:0;font-weight:500;color:var(--pbb-ink)}\n.pbb-value{text-align:right;overflow-wrap:anywhere}\n.pbb-token{max-width:100%;font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--pbb-secondary);overflow-wrap:anywhere}\n.pbb-empty{margin:0;padding:16px;font-size:14px;line-height:20px;color:var(--pbb-secondary)}\n.pbb-limitRow{display:flex;align-items:center;gap:12px}\n.pbb-limitControl{display:flex;align-items:center;gap:8px;flex:none}\n.pbb-numberInput,.pbb-deviceNameInput{min-width:0;height:28px;border:1px solid var(--pbb-line);border-radius:6px;background:var(--dsw-alias-bg-layer-3,var(--pbb-fill));color:var(--pbb-ink);font:inherit;font-size:14px;line-height:20px;padding:3px 8px;caret-color:var(--pbb-ink)}\n.pbb-numberInput{width:72px}\n.pbb-numberInput:disabled,.pbb-deviceNameInput:disabled{opacity:.5}\n.pbb-endpoint{user-select:all}\n.pbb-devicesSection{display:flex;flex-direction:column;gap:8px}\n.pbb-devicesHeader{display:flex;align-items:center;gap:8px;min-height:44px;padding:0 2px}\n.pbb-deviceCount{font-size:12px;line-height:18px;color:var(--pbb-secondary);white-space:nowrap}\n.pbb-devicesCard{overflow:visible}\n.pbb-deviceList{display:flex;flex-direction:column}\n.pbb-deviceRow{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:12px;row-gap:0;min-height:56px;padding:6px 14px 6px 16px}\n.pbb-deviceRow+.pbb-deviceRow::before{content:\"\";position:absolute;top:0;left:46px;right:16px;border-top:1px solid var(--pbb-line)}\n.pbb-deviceRow:has(details[open]){z-index:2}\n.pbb-deviceMain{display:flex;align-items:center;gap:12px;min-width:0}\n.pbb-deviceMain>.pbb-icon{color:var(--pbb-secondary)}\n.pbb-deviceText{display:flex;flex-direction:column;gap:2px;min-width:0}\n.pbb-deviceName{font-size:14px;line-height:20px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.pbb-deviceMeta{display:flex;flex-wrap:wrap;gap:0 6px;color:var(--pbb-secondary);font-size:12px;line-height:18px}\n.pbb-deviceMeta>*+*::before{content:\"\\00B7\";margin-right:6px}\n.pbb-deviceActions{grid-row:1;grid-column:2;display:flex;align-items:center}\n.pbb-deviceRenameForm,.pbb-deviceConfirm{grid-column:1/-1;display:flex;gap:8px;padding:8px 0;min-width:0}\n.pbb-deviceRenameForm{flex-wrap:wrap}\n.pbb-deviceNameInput{flex:1}\n.pbb-deviceRenameActions{display:flex;align-items:center;gap:5px;flex:none}\n.pbb-deviceConfirm{flex-direction:column}\n.pbb-deviceMessage{padding:10px 16px}\n.pbb-deviceMenu{position:relative}\n.pbb-deviceMenu>summary{list-style:none}\n.pbb-deviceMenu>summary::-webkit-details-marker{display:none}\n.pbb-deviceMenuBody{position:absolute;z-index:3;top:34px;right:0;width:250px;max-width:calc(100cqw - 32px);padding:5px;border:1px solid var(--pbb-line);border-radius:10px;background:var(--dsw-alias-bg-layer-3,var(--pbb-fill));box-shadow:0 8px 24px color-mix(in srgb,var(--pbb-ink) 12%,transparent)}\n.pbb-deviceMenuInfo{display:flex;flex-direction:column;gap:3px;padding:7px 8px 10px;border-bottom:1px solid var(--pbb-line)}\n.pbb-menuAction{display:block;width:100%;min-height:32px;padding:5px 8px;border:0;border-radius:5px;background:transparent;color:var(--pbb-ink);text-align:left;font:inherit;font-size:14px;cursor:pointer}\n.pbb-menuDanger{color:var(--dsw-alias-state-error-primary,#bc2222)}\n.pbb-actionBusy{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--pbb-secondary)}\n.pbb-actionBusy::before{content:\"\";width:10px;height:10px;border:1.5px solid var(--pbb-line);border-top-color:currentColor;border-radius:50%;animation:pbb-spin .7s linear infinite}\n@keyframes pbb-spin{to{transform:rotate(360deg)}}\n.pbb-rowAction{display:flex;flex-wrap:wrap;gap:8px}\n.pbb-pairingPanel{border:1px solid var(--pbb-line);border-radius:16px;padding:16px;background:var(--pbb-fill)}\n.pbb-pairingHeader{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}\n.pbb-pairingBody{display:flex;flex-direction:column;gap:10px}\n.pbb-targetList{display:flex;flex-wrap:wrap;gap:4px;min-width:0}\n.pbb-targetButton{max-width:100%;padding:5px 9px;border:1px solid transparent;border-radius:7px;background:var(--pbb-soft);color:var(--pbb-secondary);font:inherit;font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}\n.pbb-targetSelected{color:var(--pbb-ink);border-color:var(--pbb-line);background:var(--pbb-fill)}\n.pbb-qrPanel{display:grid;grid-template-columns:224px minmax(0,1fr);gap:20px;align-items:start}\n.pbb-qrImage{display:block;width:224px;height:224px;max-width:100%;padding:8px;border-radius:12px;background:#fff}\n.pbb-countdown{margin-top:10px;display:flex;flex-direction:column;gap:6px}\n.pbb-countdownBar{height:4px;border-radius:99px;background:var(--pbb-soft);overflow:hidden}\n.pbb-countdownBar i{display:block;width:100%;height:100%;transform-origin:left center;background:var(--dsw-alias-state-business-primary,#4176e6);border-radius:99px}\n.pbb-countdownText{font-size:12px;line-height:18px;color:var(--pbb-secondary);font-variant-numeric:tabular-nums}\n.pbb-pairInfo,.pbb-pairCodeBlock{display:flex;flex-direction:column;gap:8px;min-width:0}\n.pbb-pairCodeLabel,.pbb-qrHint{font-size:12px;line-height:18px;color:var(--pbb-secondary);margin:0}\n.pbb-pairCodeRow{display:flex;flex-wrap:wrap;align-items:center;gap:8px}\n.pbb-pairCode{font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;overflow-wrap:anywhere;user-select:all}\n.pbb-tools{border-radius:16px;overflow:hidden}\n.pbb-toolSection+.pbb-toolSection{border-top:1px solid var(--pbb-line)}\n.pbb-cardHead{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;padding:0 16px;border:0;background:transparent;color:var(--pbb-secondary);font:inherit;text-align:left;cursor:pointer}\n.pbb-cardHead>.pbb-cardTitle{flex:1;font-weight:400}\n.pbb-toolMeta{max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;color:var(--pbb-secondary)}\n.pbb-toolMeta.pbb-ok{color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#287a45) 65%,var(--pbb-ink))}\n.pbb-toolMeta.pbb-bad{color:var(--dsw-alias-state-error-primary,#bc2222)}\n.pbb-testGrid{display:flex;flex-direction:column;gap:0}\n.pbb-testItem{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--pbb-line)}\n.pbb-testTitle{font-size:14px;line-height:20px;font-weight:500;color:var(--pbb-ink)}\n.pbb-testDescription{font-size:12px;line-height:18px;color:var(--pbb-secondary)}\n.pbb-helpBody,.pbb-disclosureBody{display:flex;flex-direction:column;gap:14px}\n.pbb-helpSection{display:flex;flex-direction:column;gap:6px}\n.pbb-helpHeading{font-size:14px;line-height:20px;font-weight:500;color:var(--pbb-ink)}\n.pbb-helpList{margin:0;padding-left:20px;font-size:14px;line-height:22px;color:var(--pbb-secondary)}\n.pbb-helpList li+li{margin-top:4px}\n.pbb-helpText{margin:0;font-size:14px;line-height:22px;color:var(--pbb-secondary)}\n.pbb-helpCode{display:block;margin:0;padding:10px;border:1px solid var(--pbb-line);border-radius:8px;background:var(--pbb-soft);color:var(--pbb-ink);font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap;overflow-wrap:anywhere}\n.pbb-helpLink{color:var(--pbb-ink);text-decoration:underline;text-underline-offset:3px}\n.pbb-helpDisclosure>summary{display:flex;align-items:center;gap:6px;min-height:28px;list-style:none;cursor:pointer;color:var(--pbb-secondary);font-size:12px}\n.pbb-helpDisclosure>summary::-webkit-details-marker{display:none}\n.pbb-helpDisclosure[open]>.pbb-helpBody{padding-top:10px}\n.pbb-runtimeList{display:flex;flex-direction:column}\n.pbb-runtimeRow{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--pbb-line)}\n.pbb-runtimeRow>.pbb-row{flex:1;min-width:0}\n.pbb-updateRow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;color:var(--pbb-ink);font-size:14px;text-decoration:none}\n.pbb-resultRow{display:flex;align-items:flex-start;gap:6px}\n.pbb-resultIcon{display:inline-flex;flex:none;margin-top:3px;color:var(--dsw-alias-state-success-primary,#287a45)}\n.pbb-resultIconBad{color:var(--dsw-alias-state-error-primary,#bc2222)}\n.pbb-disclosure>summary{list-style:none;display:flex;align-items:center;gap:10px;min-height:44px;padding:0 16px;cursor:pointer;font-size:14px}\n.pbb-disclosure>summary::-webkit-details-marker{display:none}\n.pbb-disclosureBody{padding:2px 16px 16px}\n.pbb-disclosureTitle{flex:1}\n.pbb-section :is(.pbb-action,.pbb-refresh,.pbb-iconButton,.pbb-cardHead,.pbb-menuAction,.pbb-targetButton,input,summary,a):focus-visible{outline:2px solid var(--dsw-focus-ring-color,#5276b4);outline-offset:2px}\n@media (hover:hover) and (pointer:fine){.pbb-refresh:hover:not(:disabled),.pbb-iconButton:hover,.pbb-action:hover:not(:disabled),.pbb-cardHead:hover,.pbb-menuAction:hover:not(:disabled){background:var(--pbb-soft)}.pbb-buttonPrimary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,#30343b)}.pbb-action:active:not(:disabled),.pbb-refresh:active:not(:disabled),.pbb-iconButton:active{transform:scale(.97)}}\n@media (prefers-reduced-motion:reduce){.pbb-action,.pbb-refresh,.pbb-iconButton{transition:none;transform:none!important}.pbb-actionBusy::before{animation:none}}\n@container pbb (max-width:480px){.pbb-qrPanel{grid-template-columns:1fr}.pbb-limitRow{align-items:flex-start;flex-direction:column}.pbb-limitControl{align-self:flex-end}.pbb-deviceMeta{column-gap:4px}.pbb-toolMeta{max-width:42%}.pbb-channelRow{gap:8px}.pbb-testItem{flex-wrap:wrap}.pbb-testItem>.pbb-controlText{flex-basis:65%}}\n@container pbb (max-width:340px){.pbb-devicesHeader{flex-wrap:wrap}.pbb-deviceRow{column-gap:6px;padding-right:10px}.pbb-channelBody{padding-left:16px}.pbb-toolMeta{max-width:38%}}\n@media (pointer:coarse){.pbb-action,.pbb-iconButton,.pbb-refresh,.pbb-targetButton,.pbb-menuAction,.pbb-helpDisclosure>summary{min-width:44px;min-height:44px}.pbb-numberInput,.pbb-deviceNameInput{height:44px;font-size:16px}.pbb-deviceMenuBody{top:48px}}\n`\n\n/**\n * Client bundle id, identical to the `window.__ModuleLoader__.load({ id })`\n * identity emitted by tsdown.config.ts. DSH's module system owns style\n * teardown by package id, so this tag must carry the same value.\n */\nconst PLUGIN_ID = 'dsh-deeppilot'\n\n/**\n * Claim this plugin's page stylesheet against DSH's style ownership.\n *\n * `ClientModuleSystem` tags untagged `<style>` elements only during factory\n * materialization; this sheet is injected from `apply()`, which runs after\n * that point, so it would never be attributed to us. Stamping `data-plugin`\n * ourselves lets the module system's `removeOwnedStyles(id)` delete the sheet\n * when the plugin is unloaded at runtime — the rc.2 Plugin Manager and client\n * entry reconciler both support live removal, and an\n * orphaned sheet would otherwise keep styling a page we no longer own.\n */\nexport function injectCss(): void {\n if (typeof document === 'undefined') return\n const id = 'dsh-deeppilot/page.css'\n if (document.querySelector('style[data-plugin-css=\"' + id + '\"]') !== null) return\n const tag = document.createElement('style')\n tag.setAttribute('data-plugin', PLUGIN_ID)\n tag.setAttribute('data-plugin-css', id)\n tag.textContent = CSS\n document.head.appendChild(tag)\n}\n","import { createElement as h } from 'react'\n\ntype IconName = 'phone' | 'wifi' | 'globe' | 'refresh' | 'plus' | 'more' | 'activity' | 'info' | 'ready' | 'attention'\n\n/** 设置页的小图标共用线宽与 currentColor,随宿主主题变色,不额外引入图标包。 */\nexport function settingsIcon(name: IconName, size = 18): any {\n const path = (d: string): any => h('path', { d })\n const circle = (cx: number, cy: number, r: number): any => h('circle', { cx, cy, r })\n const shapes: Record<IconName, () => any[]> = {\n phone: () => [h('rect', { x: 6.5, y: 2.5, width: 11, height: 19, rx: 2.2 }), path('M10 5h4M11 18.5h2')],\n wifi: () => [path('M2 8.8a16 16 0 0 1 20 0M5 12.1a11 11 0 0 1 14 0M8.3 15.5a6 6 0 0 1 7.4 0'), circle(12, 19, .7)],\n globe: () => [circle(12, 12, 9), path('M3 12h18M12 3a17 17 0 0 1 0 18 17 17 0 0 1 0-18')],\n refresh: () => [path('M20 7v5h-5M4 17v-5h5M6.1 7a7 7 0 0 1 11.5-1L20 9M4 15l2.4 3A7 7 0 0 0 18 17')],\n plus: () => [path('M12 5v14M5 12h14')],\n more: () => [circle(5, 12, 1.2), circle(12, 12, 1.2), circle(19, 12, 1.2)],\n activity: () => [path('M3 12h4l3-7 4 14 3-7h4')],\n info: () => [circle(12, 12, 9), path('M12 11v6M12 7h.01')],\n ready: () => [circle(12, 12, 9), path('m8 12 3 3 5-6')],\n attention: () => [circle(12, 12, 9), path('M12 7v6M12 17h.01')],\n }\n return h('svg', {\n className: 'pbb-icon', viewBox: '0 0 24 24', width: size, height: size,\n fill: 'none', stroke: 'currentColor', strokeWidth: 1.6,\n strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true,\n }, ...shapes[name]())\n}\n","import { createElement as h, useEffect, useRef } from 'react'\nimport type { Translate } from './i18n.ts'\nimport { settingsIcon } from './settings-icons.ts'\n\ninterface DeviceActionsProps {\n name: string\n fingerprint: string\n customName?: string\n canRename: boolean\n canRevoke: boolean\n onRename: () => void\n onRevoke: () => void\n t: Translate\n}\n\n/**\n * 原生 disclosure(折叠控件)负责 Enter/Space 与焦点顺序;操作仍是普通按钮,\n * 不冒充需要方向键导航的 ARIA menu。详情只在展开时进入无障碍读取顺序。\n */\nexport function DeviceActions(props: DeviceActionsProps): any {\n const ref = useRef<HTMLDetailsElement>(null)\n const close = (restoreFocus = false): void => {\n const details = ref.current\n if (details === null) return\n details.open = false\n if (restoreFocus) details.querySelector('summary')?.focus()\n }\n useEffect(() => {\n const outside = (event: PointerEvent): void => {\n if (event.target instanceof Node && !ref.current?.contains(event.target)) close()\n }\n document.addEventListener('pointerdown', outside)\n return () => document.removeEventListener('pointerdown', outside)\n }, [])\n const act = (action: () => void): void => { close(); action() }\n return h('details', {\n ref, className: 'pbb-deviceMenu',\n onKeyDown: (event: { key: string; preventDefault: () => void; stopPropagation: () => void }) => {\n if (event.key !== 'Escape' || !ref.current?.open) return\n event.preventDefault()\n event.stopPropagation()\n close(true)\n },\n },\n h('summary', {\n className: 'pbb-iconButton',\n 'aria-label': props.t('devices.moreAria', { name: props.name }),\n }, settingsIcon('more', 16)),\n h('div', { className: 'pbb-deviceMenuBody', 'aria-label': props.t('devices.col.actions') },\n h('div', { className: 'pbb-deviceMenuInfo' },\n props.customName ? h('span', { className: 'pbb-diag' }, props.t('devices.customBadge')) : null,\n h('span', { className: 'pbb-diag' }, props.t('devices.col.fingerprint')),\n h('code', { className: 'pbb-token' }, props.fingerprint || '—')),\n h('button', {\n type: 'button', className: 'pbb-menuAction', disabled: !props.canRename,\n 'aria-label': props.t('devices.renameAria', { name: props.name }),\n onClick: () => act(props.onRename),\n }, props.t('devices.rename')),\n h('button', {\n type: 'button', className: 'pbb-menuAction pbb-menuDanger', disabled: !props.canRevoke,\n 'aria-label': props.t('devices.revokeAria', { name: props.name }),\n onClick: () => act(props.onRevoke),\n }, props.t('devices.revoke'))))\n}\n","// can-promise has a crash in some versions of react native that dont have\n// standard global objects\n// https://github.com/soldair/node-qrcode/issues/157\n\nmodule.exports = function () {\n return typeof Promise === 'function' && Promise.prototype && Promise.prototype.then\n}\n","let toSJISFunction\nconst CODEWORDS_COUNT = [\n 0, // Not used\n 26, 44, 70, 100, 134, 172, 196, 242, 292, 346,\n 404, 466, 532, 581, 655, 733, 815, 901, 991, 1085,\n 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 2185,\n 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706\n]\n\n/**\n * Returns the QR Code size for the specified version\n *\n * @param {Number} version QR Code version\n * @return {Number} size of QR code\n */\nexports.getSymbolSize = function getSymbolSize (version) {\n if (!version) throw new Error('\"version\" cannot be null or undefined')\n if (version < 1 || version > 40) throw new Error('\"version\" should be in range from 1 to 40')\n return version * 4 + 17\n}\n\n/**\n * Returns the total number of codewords used to store data and EC information.\n *\n * @param {Number} version QR Code version\n * @return {Number} Data length in bits\n */\nexports.getSymbolTotalCodewords = function getSymbolTotalCodewords (version) {\n return CODEWORDS_COUNT[version]\n}\n\n/**\n * Encode data with Bose-Chaudhuri-Hocquenghem\n *\n * @param {Number} data Value to encode\n * @return {Number} Encoded value\n */\nexports.getBCHDigit = function (data) {\n let digit = 0\n\n while (data !== 0) {\n digit++\n data >>>= 1\n }\n\n return digit\n}\n\nexports.setToSJISFunction = function setToSJISFunction (f) {\n if (typeof f !== 'function') {\n throw new Error('\"toSJISFunc\" is not a valid function.')\n }\n\n toSJISFunction = f\n}\n\nexports.isKanjiModeEnabled = function () {\n return typeof toSJISFunction !== 'undefined'\n}\n\nexports.toSJIS = function toSJIS (kanji) {\n return toSJISFunction(kanji)\n}\n","exports.L = { bit: 1 }\nexports.M = { bit: 0 }\nexports.Q = { bit: 3 }\nexports.H = { bit: 2 }\n\nfunction fromString (string) {\n if (typeof string !== 'string') {\n throw new Error('Param is not a string')\n }\n\n const lcStr = string.toLowerCase()\n\n switch (lcStr) {\n case 'l':\n case 'low':\n return exports.L\n\n case 'm':\n case 'medium':\n return exports.M\n\n case 'q':\n case 'quartile':\n return exports.Q\n\n case 'h':\n case 'high':\n return exports.H\n\n default:\n throw new Error('Unknown EC Level: ' + string)\n }\n}\n\nexports.isValid = function isValid (level) {\n return level && typeof level.bit !== 'undefined' &&\n level.bit >= 0 && level.bit < 4\n}\n\nexports.from = function from (value, defaultValue) {\n if (exports.isValid(value)) {\n return value\n }\n\n try {\n return fromString(value)\n } catch (e) {\n return defaultValue\n }\n}\n","function BitBuffer () {\n this.buffer = []\n this.length = 0\n}\n\nBitBuffer.prototype = {\n\n get: function (index) {\n const bufIndex = Math.floor(index / 8)\n return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) === 1\n },\n\n put: function (num, length) {\n for (let i = 0; i < length; i++) {\n this.putBit(((num >>> (length - i - 1)) & 1) === 1)\n }\n },\n\n getLengthInBits: function () {\n return this.length\n },\n\n putBit: function (bit) {\n const bufIndex = Math.floor(this.length / 8)\n if (this.buffer.length <= bufIndex) {\n this.buffer.push(0)\n }\n\n if (bit) {\n this.buffer[bufIndex] |= (0x80 >>> (this.length % 8))\n }\n\n this.length++\n }\n}\n\nmodule.exports = BitBuffer\n","/**\n * Helper class to handle QR Code symbol modules\n *\n * @param {Number} size Symbol size\n */\nfunction BitMatrix (size) {\n if (!size || size < 1) {\n throw new Error('BitMatrix size must be defined and greater than 0')\n }\n\n this.size = size\n this.data = new Uint8Array(size * size)\n this.reservedBit = new Uint8Array(size * size)\n}\n\n/**\n * Set bit value at specified location\n * If reserved flag is set, this bit will be ignored during masking process\n *\n * @param {Number} row\n * @param {Number} col\n * @param {Boolean} value\n * @param {Boolean} reserved\n */\nBitMatrix.prototype.set = function (row, col, value, reserved) {\n const index = row * this.size + col\n this.data[index] = value\n if (reserved) this.reservedBit[index] = true\n}\n\n/**\n * Returns bit value at specified location\n *\n * @param {Number} row\n * @param {Number} col\n * @return {Boolean}\n */\nBitMatrix.prototype.get = function (row, col) {\n return this.data[row * this.size + col]\n}\n\n/**\n * Applies xor operator at specified location\n * (used during masking process)\n *\n * @param {Number} row\n * @param {Number} col\n * @param {Boolean} value\n */\nBitMatrix.prototype.xor = function (row, col, value) {\n this.data[row * this.size + col] ^= value\n}\n\n/**\n * Check if bit at specified location is reserved\n *\n * @param {Number} row\n * @param {Number} col\n * @return {Boolean}\n */\nBitMatrix.prototype.isReserved = function (row, col) {\n return this.reservedBit[row * this.size + col]\n}\n\nmodule.exports = BitMatrix\n","/**\n * Alignment pattern are fixed reference pattern in defined positions\n * in a matrix symbology, which enables the decode software to re-synchronise\n * the coordinate mapping of the image modules in the event of moderate amounts\n * of distortion of the image.\n *\n * Alignment patterns are present only in QR Code symbols of version 2 or larger\n * and their number depends on the symbol version.\n */\n\nconst getSymbolSize = require('./utils').getSymbolSize\n\n/**\n * Calculate the row/column coordinates of the center module of each alignment pattern\n * for the specified QR Code version.\n *\n * The alignment patterns are positioned symmetrically on either side of the diagonal\n * running from the top left corner of the symbol to the bottom right corner.\n *\n * Since positions are simmetrical only half of the coordinates are returned.\n * Each item of the array will represent in turn the x and y coordinate.\n * @see {@link getPositions}\n *\n * @param {Number} version QR Code version\n * @return {Array} Array of coordinate\n */\nexports.getRowColCoords = function getRowColCoords (version) {\n if (version === 1) return []\n\n const posCount = Math.floor(version / 7) + 2\n const size = getSymbolSize(version)\n const intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2\n const positions = [size - 7] // Last coord is always (size - 7)\n\n for (let i = 1; i < posCount - 1; i++) {\n positions[i] = positions[i - 1] - intervals\n }\n\n positions.push(6) // First coord is always 6\n\n return positions.reverse()\n}\n\n/**\n * Returns an array containing the positions of each alignment pattern.\n * Each array's element represent the center point of the pattern as (x, y) coordinates\n *\n * Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords}\n * and filtering out the items that overlaps with finder pattern\n *\n * @example\n * For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38.\n * The alignment patterns, therefore, are to be centered on (row, column)\n * positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38).\n * Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns\n * and are not therefore used for alignment patterns.\n *\n * let pos = getPositions(7)\n * // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]]\n *\n * @param {Number} version QR Code version\n * @return {Array} Array of coordinates\n */\nexports.getPositions = function getPositions (version) {\n const coords = []\n const pos = exports.getRowColCoords(version)\n const posLength = pos.length\n\n for (let i = 0; i < posLength; i++) {\n for (let j = 0; j < posLength; j++) {\n // Skip if position is occupied by finder patterns\n if ((i === 0 && j === 0) || // top-left\n (i === 0 && j === posLength - 1) || // bottom-left\n (i === posLength - 1 && j === 0)) { // top-right\n continue\n }\n\n coords.push([pos[i], pos[j]])\n }\n }\n\n return coords\n}\n","const getSymbolSize = require('./utils').getSymbolSize\nconst FINDER_PATTERN_SIZE = 7\n\n/**\n * Returns an array containing the positions of each finder pattern.\n * Each array's element represent the top-left point of the pattern as (x, y) coordinates\n *\n * @param {Number} version QR Code version\n * @return {Array} Array of coordinates\n */\nexports.getPositions = function getPositions (version) {\n const size = getSymbolSize(version)\n\n return [\n // top-left\n [0, 0],\n // top-right\n [size - FINDER_PATTERN_SIZE, 0],\n // bottom-left\n [0, size - FINDER_PATTERN_SIZE]\n ]\n}\n","/**\n * Data mask pattern reference\n * @type {Object}\n */\nexports.Patterns = {\n PATTERN000: 0,\n PATTERN001: 1,\n PATTERN010: 2,\n PATTERN011: 3,\n PATTERN100: 4,\n PATTERN101: 5,\n PATTERN110: 6,\n PATTERN111: 7\n}\n\n/**\n * Weighted penalty scores for the undesirable features\n * @type {Object}\n */\nconst PenaltyScores = {\n N1: 3,\n N2: 3,\n N3: 40,\n N4: 10\n}\n\n/**\n * Check if mask pattern value is valid\n *\n * @param {Number} mask Mask pattern\n * @return {Boolean} true if valid, false otherwise\n */\nexports.isValid = function isValid (mask) {\n return mask != null && mask !== '' && !isNaN(mask) && mask >= 0 && mask <= 7\n}\n\n/**\n * Returns mask pattern from a value.\n * If value is not valid, returns undefined\n *\n * @param {Number|String} value Mask pattern value\n * @return {Number} Valid mask pattern or undefined\n */\nexports.from = function from (value) {\n return exports.isValid(value) ? parseInt(value, 10) : undefined\n}\n\n/**\n* Find adjacent modules in row/column with the same color\n* and assign a penalty value.\n*\n* Points: N1 + i\n* i is the amount by which the number of adjacent modules of the same color exceeds 5\n*/\nexports.getPenaltyN1 = function getPenaltyN1 (data) {\n const size = data.size\n let points = 0\n let sameCountCol = 0\n let sameCountRow = 0\n let lastCol = null\n let lastRow = null\n\n for (let row = 0; row < size; row++) {\n sameCountCol = sameCountRow = 0\n lastCol = lastRow = null\n\n for (let col = 0; col < size; col++) {\n let module = data.get(row, col)\n if (module === lastCol) {\n sameCountCol++\n } else {\n if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5)\n lastCol = module\n sameCountCol = 1\n }\n\n module = data.get(col, row)\n if (module === lastRow) {\n sameCountRow++\n } else {\n if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5)\n lastRow = module\n sameCountRow = 1\n }\n }\n\n if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5)\n if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5)\n }\n\n return points\n}\n\n/**\n * Find 2x2 blocks with the same color and assign a penalty value\n *\n * Points: N2 * (m - 1) * (n - 1)\n */\nexports.getPenaltyN2 = function getPenaltyN2 (data) {\n const size = data.size\n let points = 0\n\n for (let row = 0; row < size - 1; row++) {\n for (let col = 0; col < size - 1; col++) {\n const last = data.get(row, col) +\n data.get(row, col + 1) +\n data.get(row + 1, col) +\n data.get(row + 1, col + 1)\n\n if (last === 4 || last === 0) points++\n }\n }\n\n return points * PenaltyScores.N2\n}\n\n/**\n * Find 1:1:3:1:1 ratio (dark:light:dark:light:dark) pattern in row/column,\n * preceded or followed by light area 4 modules wide\n *\n * Points: N3 * number of pattern found\n */\nexports.getPenaltyN3 = function getPenaltyN3 (data) {\n const size = data.size\n let points = 0\n let bitsCol = 0\n let bitsRow = 0\n\n for (let row = 0; row < size; row++) {\n bitsCol = bitsRow = 0\n for (let col = 0; col < size; col++) {\n bitsCol = ((bitsCol << 1) & 0x7FF) | data.get(row, col)\n if (col >= 10 && (bitsCol === 0x5D0 || bitsCol === 0x05D)) points++\n\n bitsRow = ((bitsRow << 1) & 0x7FF) | data.get(col, row)\n if (col >= 10 && (bitsRow === 0x5D0 || bitsRow === 0x05D)) points++\n }\n }\n\n return points * PenaltyScores.N3\n}\n\n/**\n * Calculate proportion of dark modules in entire symbol\n *\n * Points: N4 * k\n *\n * k is the rating of the deviation of the proportion of dark modules\n * in the symbol from 50% in steps of 5%\n */\nexports.getPenaltyN4 = function getPenaltyN4 (data) {\n let darkCount = 0\n const modulesCount = data.data.length\n\n for (let i = 0; i < modulesCount; i++) darkCount += data.data[i]\n\n const k = Math.abs(Math.ceil((darkCount * 100 / modulesCount) / 5) - 10)\n\n return k * PenaltyScores.N4\n}\n\n/**\n * Return mask value at given position\n *\n * @param {Number} maskPattern Pattern reference value\n * @param {Number} i Row\n * @param {Number} j Column\n * @return {Boolean} Mask value\n */\nfunction getMaskAt (maskPattern, i, j) {\n switch (maskPattern) {\n case exports.Patterns.PATTERN000: return (i + j) % 2 === 0\n case exports.Patterns.PATTERN001: return i % 2 === 0\n case exports.Patterns.PATTERN010: return j % 3 === 0\n case exports.Patterns.PATTERN011: return (i + j) % 3 === 0\n case exports.Patterns.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0\n case exports.Patterns.PATTERN101: return (i * j) % 2 + (i * j) % 3 === 0\n case exports.Patterns.PATTERN110: return ((i * j) % 2 + (i * j) % 3) % 2 === 0\n case exports.Patterns.PATTERN111: return ((i * j) % 3 + (i + j) % 2) % 2 === 0\n\n default: throw new Error('bad maskPattern:' + maskPattern)\n }\n}\n\n/**\n * Apply a mask pattern to a BitMatrix\n *\n * @param {Number} pattern Pattern reference number\n * @param {BitMatrix} data BitMatrix data\n */\nexports.applyMask = function applyMask (pattern, data) {\n const size = data.size\n\n for (let col = 0; col < size; col++) {\n for (let row = 0; row < size; row++) {\n if (data.isReserved(row, col)) continue\n data.xor(row, col, getMaskAt(pattern, row, col))\n }\n }\n}\n\n/**\n * Returns the best mask pattern for data\n *\n * @param {BitMatrix} data\n * @return {Number} Mask pattern reference number\n */\nexports.getBestMask = function getBestMask (data, setupFormatFunc) {\n const numPatterns = Object.keys(exports.Patterns).length\n let bestPattern = 0\n let lowerPenalty = Infinity\n\n for (let p = 0; p < numPatterns; p++) {\n setupFormatFunc(p)\n exports.applyMask(p, data)\n\n // Calculate penalty\n const penalty =\n exports.getPenaltyN1(data) +\n exports.getPenaltyN2(data) +\n exports.getPenaltyN3(data) +\n exports.getPenaltyN4(data)\n\n // Undo previously applied mask\n exports.applyMask(p, data)\n\n if (penalty < lowerPenalty) {\n lowerPenalty = penalty\n bestPattern = p\n }\n }\n\n return bestPattern\n}\n","const ECLevel = require('./error-correction-level')\r\n\r\nconst EC_BLOCKS_TABLE = [\r\n// L M Q H\r\n 1, 1, 1, 1,\r\n 1, 1, 1, 1,\r\n 1, 1, 2, 2,\r\n 1, 2, 2, 4,\r\n 1, 2, 4, 4,\r\n 2, 4, 4, 4,\r\n 2, 4, 6, 5,\r\n 2, 4, 6, 6,\r\n 2, 5, 8, 8,\r\n 4, 5, 8, 8,\r\n 4, 5, 8, 11,\r\n 4, 8, 10, 11,\r\n 4, 9, 12, 16,\r\n 4, 9, 16, 16,\r\n 6, 10, 12, 18,\r\n 6, 10, 17, 16,\r\n 6, 11, 16, 19,\r\n 6, 13, 18, 21,\r\n 7, 14, 21, 25,\r\n 8, 16, 20, 25,\r\n 8, 17, 23, 25,\r\n 9, 17, 23, 34,\r\n 9, 18, 25, 30,\r\n 10, 20, 27, 32,\r\n 12, 21, 29, 35,\r\n 12, 23, 34, 37,\r\n 12, 25, 34, 40,\r\n 13, 26, 35, 42,\r\n 14, 28, 38, 45,\r\n 15, 29, 40, 48,\r\n 16, 31, 43, 51,\r\n 17, 33, 45, 54,\r\n 18, 35, 48, 57,\r\n 19, 37, 51, 60,\r\n 19, 38, 53, 63,\r\n 20, 40, 56, 66,\r\n 21, 43, 59, 70,\r\n 22, 45, 62, 74,\r\n 24, 47, 65, 77,\r\n 25, 49, 68, 81\r\n]\r\n\r\nconst EC_CODEWORDS_TABLE = [\r\n// L M Q H\r\n 7, 10, 13, 17,\r\n 10, 16, 22, 28,\r\n 15, 26, 36, 44,\r\n 20, 36, 52, 64,\r\n 26, 48, 72, 88,\r\n 36, 64, 96, 112,\r\n 40, 72, 108, 130,\r\n 48, 88, 132, 156,\r\n 60, 110, 160, 192,\r\n 72, 130, 192, 224,\r\n 80, 150, 224, 264,\r\n 96, 176, 260, 308,\r\n 104, 198, 288, 352,\r\n 120, 216, 320, 384,\r\n 132, 240, 360, 432,\r\n 144, 280, 408, 480,\r\n 168, 308, 448, 532,\r\n 180, 338, 504, 588,\r\n 196, 364, 546, 650,\r\n 224, 416, 600, 700,\r\n 224, 442, 644, 750,\r\n 252, 476, 690, 816,\r\n 270, 504, 750, 900,\r\n 300, 560, 810, 960,\r\n 312, 588, 870, 1050,\r\n 336, 644, 952, 1110,\r\n 360, 700, 1020, 1200,\r\n 390, 728, 1050, 1260,\r\n 420, 784, 1140, 1350,\r\n 450, 812, 1200, 1440,\r\n 480, 868, 1290, 1530,\r\n 510, 924, 1350, 1620,\r\n 540, 980, 1440, 1710,\r\n 570, 1036, 1530, 1800,\r\n 570, 1064, 1590, 1890,\r\n 600, 1120, 1680, 1980,\r\n 630, 1204, 1770, 2100,\r\n 660, 1260, 1860, 2220,\r\n 720, 1316, 1950, 2310,\r\n 750, 1372, 2040, 2430\r\n]\r\n\r\n/**\r\n * Returns the number of error correction block that the QR Code should contain\r\n * for the specified version and error correction level.\r\n *\r\n * @param {Number} version QR Code version\r\n * @param {Number} errorCorrectionLevel Error correction level\r\n * @return {Number} Number of error correction blocks\r\n */\r\nexports.getBlocksCount = function getBlocksCount (version, errorCorrectionLevel) {\r\n switch (errorCorrectionLevel) {\r\n case ECLevel.L:\r\n return EC_BLOCKS_TABLE[(version - 1) * 4 + 0]\r\n case ECLevel.M:\r\n return EC_BLOCKS_TABLE[(version - 1) * 4 + 1]\r\n case ECLevel.Q:\r\n return EC_BLOCKS_TABLE[(version - 1) * 4 + 2]\r\n case ECLevel.H:\r\n return EC_BLOCKS_TABLE[(version - 1) * 4 + 3]\r\n default:\r\n return undefined\r\n }\r\n}\r\n\r\n/**\r\n * Returns the number of error correction codewords to use for the specified\r\n * version and error correction level.\r\n *\r\n * @param {Number} version QR Code version\r\n * @param {Number} errorCorrectionLevel Error correction level\r\n * @return {Number} Number of error correction codewords\r\n */\r\nexports.getTotalCodewordsCount = function getTotalCodewordsCount (version, errorCorrectionLevel) {\r\n switch (errorCorrectionLevel) {\r\n case ECLevel.L:\r\n return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0]\r\n case ECLevel.M:\r\n return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1]\r\n case ECLevel.Q:\r\n return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2]\r\n case ECLevel.H:\r\n return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3]\r\n default:\r\n return undefined\r\n }\r\n}\r\n","const EXP_TABLE = new Uint8Array(512)\nconst LOG_TABLE = new Uint8Array(256)\n/**\n * Precompute the log and anti-log tables for faster computation later\n *\n * For each possible value in the galois field 2^8, we will pre-compute\n * the logarithm and anti-logarithm (exponential) of this value\n *\n * ref {@link https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders#Introduction_to_mathematical_fields}\n */\n;(function initTables () {\n let x = 1\n for (let i = 0; i < 255; i++) {\n EXP_TABLE[i] = x\n LOG_TABLE[x] = i\n\n x <<= 1 // multiply by 2\n\n // The QR code specification says to use byte-wise modulo 100011101 arithmetic.\n // This means that when a number is 256 or larger, it should be XORed with 0x11D.\n if (x & 0x100) { // similar to x >= 256, but a lot faster (because 0x100 == 256)\n x ^= 0x11D\n }\n }\n\n // Optimization: double the size of the anti-log table so that we don't need to mod 255 to\n // stay inside the bounds (because we will mainly use this table for the multiplication of\n // two GF numbers, no more).\n // @see {@link mul}\n for (let i = 255; i < 512; i++) {\n EXP_TABLE[i] = EXP_TABLE[i - 255]\n }\n}())\n\n/**\n * Returns log value of n inside Galois Field\n *\n * @param {Number} n\n * @return {Number}\n */\nexports.log = function log (n) {\n if (n < 1) throw new Error('log(' + n + ')')\n return LOG_TABLE[n]\n}\n\n/**\n * Returns anti-log value of n inside Galois Field\n *\n * @param {Number} n\n * @return {Number}\n */\nexports.exp = function exp (n) {\n return EXP_TABLE[n]\n}\n\n/**\n * Multiplies two number inside Galois Field\n *\n * @param {Number} x\n * @param {Number} y\n * @return {Number}\n */\nexports.mul = function mul (x, y) {\n if (x === 0 || y === 0) return 0\n\n // should be EXP_TABLE[(LOG_TABLE[x] + LOG_TABLE[y]) % 255] if EXP_TABLE wasn't oversized\n // @see {@link initTables}\n return EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]]\n}\n","const GF = require('./galois-field')\n\n/**\n * Multiplies two polynomials inside Galois Field\n *\n * @param {Uint8Array} p1 Polynomial\n * @param {Uint8Array} p2 Polynomial\n * @return {Uint8Array} Product of p1 and p2\n */\nexports.mul = function mul (p1, p2) {\n const coeff = new Uint8Array(p1.length + p2.length - 1)\n\n for (let i = 0; i < p1.length; i++) {\n for (let j = 0; j < p2.length; j++) {\n coeff[i + j] ^= GF.mul(p1[i], p2[j])\n }\n }\n\n return coeff\n}\n\n/**\n * Calculate the remainder of polynomials division\n *\n * @param {Uint8Array} divident Polynomial\n * @param {Uint8Array} divisor Polynomial\n * @return {Uint8Array} Remainder\n */\nexports.mod = function mod (divident, divisor) {\n let result = new Uint8Array(divident)\n\n while ((result.length - divisor.length) >= 0) {\n const coeff = result[0]\n\n for (let i = 0; i < divisor.length; i++) {\n result[i] ^= GF.mul(divisor[i], coeff)\n }\n\n // remove all zeros from buffer head\n let offset = 0\n while (offset < result.length && result[offset] === 0) offset++\n result = result.slice(offset)\n }\n\n return result\n}\n\n/**\n * Generate an irreducible generator polynomial of specified degree\n * (used by Reed-Solomon encoder)\n *\n * @param {Number} degree Degree of the generator polynomial\n * @return {Uint8Array} Buffer containing polynomial coefficients\n */\nexports.generateECPolynomial = function generateECPolynomial (degree) {\n let poly = new Uint8Array([1])\n for (let i = 0; i < degree; i++) {\n poly = exports.mul(poly, new Uint8Array([1, GF.exp(i)]))\n }\n\n return poly\n}\n","const Polynomial = require('./polynomial')\n\nfunction ReedSolomonEncoder (degree) {\n this.genPoly = undefined\n this.degree = degree\n\n if (this.degree) this.initialize(this.degree)\n}\n\n/**\n * Initialize the encoder.\n * The input param should correspond to the number of error correction codewords.\n *\n * @param {Number} degree\n */\nReedSolomonEncoder.prototype.initialize = function initialize (degree) {\n // create an irreducible generator polynomial\n this.degree = degree\n this.genPoly = Polynomial.generateECPolynomial(this.degree)\n}\n\n/**\n * Encodes a chunk of data\n *\n * @param {Uint8Array} data Buffer containing input data\n * @return {Uint8Array} Buffer containing encoded data\n */\nReedSolomonEncoder.prototype.encode = function encode (data) {\n if (!this.genPoly) {\n throw new Error('Encoder not initialized')\n }\n\n // Calculate EC for this data block\n // extends data size to data+genPoly size\n const paddedData = new Uint8Array(data.length + this.degree)\n paddedData.set(data)\n\n // The error correction codewords are the remainder after dividing the data codewords\n // by a generator polynomial\n const remainder = Polynomial.mod(paddedData, this.genPoly)\n\n // return EC data blocks (last n byte, where n is the degree of genPoly)\n // If coefficients number in remainder are less than genPoly degree,\n // pad with 0s to the left to reach the needed number of coefficients\n const start = this.degree - remainder.length\n if (start > 0) {\n const buff = new Uint8Array(this.degree)\n buff.set(remainder, start)\n\n return buff\n }\n\n return remainder\n}\n\nmodule.exports = ReedSolomonEncoder\n","/**\n * Check if QR Code version is valid\n *\n * @param {Number} version QR Code version\n * @return {Boolean} true if valid version, false otherwise\n */\nexports.isValid = function isValid (version) {\n return !isNaN(version) && version >= 1 && version <= 40\n}\n","const numeric = '[0-9]+'\nconst alphanumeric = '[A-Z $%*+\\\\-./:]+'\nlet kanji = '(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|' +\n '[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|' +\n '[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|' +\n '[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+'\nkanji = kanji.replace(/u/g, '\\\\u')\n\nconst byte = '(?:(?![A-Z0-9 $%*+\\\\-./:]|' + kanji + ')(?:.|[\\r\\n]))+'\n\nexports.KANJI = new RegExp(kanji, 'g')\nexports.BYTE_KANJI = new RegExp('[^A-Z0-9 $%*+\\\\-./:]+', 'g')\nexports.BYTE = new RegExp(byte, 'g')\nexports.NUMERIC = new RegExp(numeric, 'g')\nexports.ALPHANUMERIC = new RegExp(alphanumeric, 'g')\n\nconst TEST_KANJI = new RegExp('^' + kanji + '$')\nconst TEST_NUMERIC = new RegExp('^' + numeric + '$')\nconst TEST_ALPHANUMERIC = new RegExp('^[A-Z0-9 $%*+\\\\-./:]+$')\n\nexports.testKanji = function testKanji (str) {\n return TEST_KANJI.test(str)\n}\n\nexports.testNumeric = function testNumeric (str) {\n return TEST_NUMERIC.test(str)\n}\n\nexports.testAlphanumeric = function testAlphanumeric (str) {\n return TEST_ALPHANUMERIC.test(str)\n}\n","const VersionCheck = require('./version-check')\nconst Regex = require('./regex')\n\n/**\n * Numeric mode encodes data from the decimal digit set (0 - 9)\n * (byte values 30HEX to 39HEX).\n * Normally, 3 data characters are represented by 10 bits.\n *\n * @type {Object}\n */\nexports.NUMERIC = {\n id: 'Numeric',\n bit: 1 << 0,\n ccBits: [10, 12, 14]\n}\n\n/**\n * Alphanumeric mode encodes data from a set of 45 characters,\n * i.e. 10 numeric digits (0 - 9),\n * 26 alphabetic characters (A - Z),\n * and 9 symbols (SP, $, %, *, +, -, ., /, :).\n * Normally, two input characters are represented by 11 bits.\n *\n * @type {Object}\n */\nexports.ALPHANUMERIC = {\n id: 'Alphanumeric',\n bit: 1 << 1,\n ccBits: [9, 11, 13]\n}\n\n/**\n * In byte mode, data is encoded at 8 bits per character.\n *\n * @type {Object}\n */\nexports.BYTE = {\n id: 'Byte',\n bit: 1 << 2,\n ccBits: [8, 16, 16]\n}\n\n/**\n * The Kanji mode efficiently encodes Kanji characters in accordance with\n * the Shift JIS system based on JIS X 0208.\n * The Shift JIS values are shifted from the JIS X 0208 values.\n * JIS X 0208 gives details of the shift coded representation.\n * Each two-byte character value is compacted to a 13-bit binary codeword.\n *\n * @type {Object}\n */\nexports.KANJI = {\n id: 'Kanji',\n bit: 1 << 3,\n ccBits: [8, 10, 12]\n}\n\n/**\n * Mixed mode will contain a sequences of data in a combination of any of\n * the modes described above\n *\n * @type {Object}\n */\nexports.MIXED = {\n bit: -1\n}\n\n/**\n * Returns the number of bits needed to store the data length\n * according to QR Code specifications.\n *\n * @param {Mode} mode Data mode\n * @param {Number} version QR Code version\n * @return {Number} Number of bits\n */\nexports.getCharCountIndicator = function getCharCountIndicator (mode, version) {\n if (!mode.ccBits) throw new Error('Invalid mode: ' + mode)\n\n if (!VersionCheck.isValid(version)) {\n throw new Error('Invalid version: ' + version)\n }\n\n if (version >= 1 && version < 10) return mode.ccBits[0]\n else if (version < 27) return mode.ccBits[1]\n return mode.ccBits[2]\n}\n\n/**\n * Returns the most efficient mode to store the specified data\n *\n * @param {String} dataStr Input data string\n * @return {Mode} Best mode\n */\nexports.getBestModeForData = function getBestModeForData (dataStr) {\n if (Regex.testNumeric(dataStr)) return exports.NUMERIC\n else if (Regex.testAlphanumeric(dataStr)) return exports.ALPHANUMERIC\n else if (Regex.testKanji(dataStr)) return exports.KANJI\n else return exports.BYTE\n}\n\n/**\n * Return mode name as string\n *\n * @param {Mode} mode Mode object\n * @returns {String} Mode name\n */\nexports.toString = function toString (mode) {\n if (mode && mode.id) return mode.id\n throw new Error('Invalid mode')\n}\n\n/**\n * Check if input param is a valid mode object\n *\n * @param {Mode} mode Mode object\n * @returns {Boolean} True if valid mode, false otherwise\n */\nexports.isValid = function isValid (mode) {\n return mode && mode.bit && mode.ccBits\n}\n\n/**\n * Get mode object from its name\n *\n * @param {String} string Mode name\n * @returns {Mode} Mode object\n */\nfunction fromString (string) {\n if (typeof string !== 'string') {\n throw new Error('Param is not a string')\n }\n\n const lcStr = string.toLowerCase()\n\n switch (lcStr) {\n case 'numeric':\n return exports.NUMERIC\n case 'alphanumeric':\n return exports.ALPHANUMERIC\n case 'kanji':\n return exports.KANJI\n case 'byte':\n return exports.BYTE\n default:\n throw new Error('Unknown mode: ' + string)\n }\n}\n\n/**\n * Returns mode from a value.\n * If value is not a valid mode, returns defaultValue\n *\n * @param {Mode|String} value Encoding mode\n * @param {Mode} defaultValue Fallback value\n * @return {Mode} Encoding mode\n */\nexports.from = function from (value, defaultValue) {\n if (exports.isValid(value)) {\n return value\n }\n\n try {\n return fromString(value)\n } catch (e) {\n return defaultValue\n }\n}\n","const Utils = require('./utils')\nconst ECCode = require('./error-correction-code')\nconst ECLevel = require('./error-correction-level')\nconst Mode = require('./mode')\nconst VersionCheck = require('./version-check')\n\n// Generator polynomial used to encode version information\nconst G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0)\nconst G18_BCH = Utils.getBCHDigit(G18)\n\nfunction getBestVersionForDataLength (mode, length, errorCorrectionLevel) {\n for (let currentVersion = 1; currentVersion <= 40; currentVersion++) {\n if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, mode)) {\n return currentVersion\n }\n }\n\n return undefined\n}\n\nfunction getReservedBitsCount (mode, version) {\n // Character count indicator + mode indicator bits\n return Mode.getCharCountIndicator(mode, version) + 4\n}\n\nfunction getTotalBitsFromDataArray (segments, version) {\n let totalBits = 0\n\n segments.forEach(function (data) {\n const reservedBits = getReservedBitsCount(data.mode, version)\n totalBits += reservedBits + data.getBitsLength()\n })\n\n return totalBits\n}\n\nfunction getBestVersionForMixedData (segments, errorCorrectionLevel) {\n for (let currentVersion = 1; currentVersion <= 40; currentVersion++) {\n const length = getTotalBitsFromDataArray(segments, currentVersion)\n if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, Mode.MIXED)) {\n return currentVersion\n }\n }\n\n return undefined\n}\n\n/**\n * Returns version number from a value.\n * If value is not a valid version, returns defaultValue\n *\n * @param {Number|String} value QR Code version\n * @param {Number} defaultValue Fallback value\n * @return {Number} QR Code version number\n */\nexports.from = function from (value, defaultValue) {\n if (VersionCheck.isValid(value)) {\n return parseInt(value, 10)\n }\n\n return defaultValue\n}\n\n/**\n * Returns how much data can be stored with the specified QR code version\n * and error correction level\n *\n * @param {Number} version QR Code version (1-40)\n * @param {Number} errorCorrectionLevel Error correction level\n * @param {Mode} mode Data mode\n * @return {Number} Quantity of storable data\n */\nexports.getCapacity = function getCapacity (version, errorCorrectionLevel, mode) {\n if (!VersionCheck.isValid(version)) {\n throw new Error('Invalid QR Code version')\n }\n\n // Use Byte mode as default\n if (typeof mode === 'undefined') mode = Mode.BYTE\n\n // Total codewords for this QR code version (Data + Error correction)\n const totalCodewords = Utils.getSymbolTotalCodewords(version)\n\n // Total number of error correction codewords\n const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)\n\n // Total number of data codewords\n const dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8\n\n if (mode === Mode.MIXED) return dataTotalCodewordsBits\n\n const usableBits = dataTotalCodewordsBits - getReservedBitsCount(mode, version)\n\n // Return max number of storable codewords\n switch (mode) {\n case Mode.NUMERIC:\n return Math.floor((usableBits / 10) * 3)\n\n case Mode.ALPHANUMERIC:\n return Math.floor((usableBits / 11) * 2)\n\n case Mode.KANJI:\n return Math.floor(usableBits / 13)\n\n case Mode.BYTE:\n default:\n return Math.floor(usableBits / 8)\n }\n}\n\n/**\n * Returns the minimum version needed to contain the amount of data\n *\n * @param {Segment} data Segment of data\n * @param {Number} [errorCorrectionLevel=H] Error correction level\n * @param {Mode} mode Data mode\n * @return {Number} QR Code version\n */\nexports.getBestVersionForData = function getBestVersionForData (data, errorCorrectionLevel) {\n let seg\n\n const ecl = ECLevel.from(errorCorrectionLevel, ECLevel.M)\n\n if (Array.isArray(data)) {\n if (data.length > 1) {\n return getBestVersionForMixedData(data, ecl)\n }\n\n if (data.length === 0) {\n return 1\n }\n\n seg = data[0]\n } else {\n seg = data\n }\n\n return getBestVersionForDataLength(seg.mode, seg.getLength(), ecl)\n}\n\n/**\n * Returns version information with relative error correction bits\n *\n * The version information is included in QR Code symbols of version 7 or larger.\n * It consists of an 18-bit sequence containing 6 data bits,\n * with 12 error correction bits calculated using the (18, 6) Golay code.\n *\n * @param {Number} version QR Code version\n * @return {Number} Encoded version info bits\n */\nexports.getEncodedBits = function getEncodedBits (version) {\n if (!VersionCheck.isValid(version) || version < 7) {\n throw new Error('Invalid QR Code version')\n }\n\n let d = version << 12\n\n while (Utils.getBCHDigit(d) - G18_BCH >= 0) {\n d ^= (G18 << (Utils.getBCHDigit(d) - G18_BCH))\n }\n\n return (version << 12) | d\n}\n","const Utils = require('./utils')\n\nconst G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0)\nconst G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1)\nconst G15_BCH = Utils.getBCHDigit(G15)\n\n/**\n * Returns format information with relative error correction bits\n *\n * The format information is a 15-bit sequence containing 5 data bits,\n * with 10 error correction bits calculated using the (15, 5) BCH code.\n *\n * @param {Number} errorCorrectionLevel Error correction level\n * @param {Number} mask Mask pattern\n * @return {Number} Encoded format information bits\n */\nexports.getEncodedBits = function getEncodedBits (errorCorrectionLevel, mask) {\n const data = ((errorCorrectionLevel.bit << 3) | mask)\n let d = data << 10\n\n while (Utils.getBCHDigit(d) - G15_BCH >= 0) {\n d ^= (G15 << (Utils.getBCHDigit(d) - G15_BCH))\n }\n\n // xor final data with mask pattern in order to ensure that\n // no combination of Error Correction Level and data mask pattern\n // will result in an all-zero data string\n return ((data << 10) | d) ^ G15_MASK\n}\n","const Mode = require('./mode')\n\nfunction NumericData (data) {\n this.mode = Mode.NUMERIC\n this.data = data.toString()\n}\n\nNumericData.getBitsLength = function getBitsLength (length) {\n return 10 * Math.floor(length / 3) + ((length % 3) ? ((length % 3) * 3 + 1) : 0)\n}\n\nNumericData.prototype.getLength = function getLength () {\n return this.data.length\n}\n\nNumericData.prototype.getBitsLength = function getBitsLength () {\n return NumericData.getBitsLength(this.data.length)\n}\n\nNumericData.prototype.write = function write (bitBuffer) {\n let i, group, value\n\n // The input data string is divided into groups of three digits,\n // and each group is converted to its 10-bit binary equivalent.\n for (i = 0; i + 3 <= this.data.length; i += 3) {\n group = this.data.substr(i, 3)\n value = parseInt(group, 10)\n\n bitBuffer.put(value, 10)\n }\n\n // If the number of input digits is not an exact multiple of three,\n // the final one or two digits are converted to 4 or 7 bits respectively.\n const remainingNum = this.data.length - i\n if (remainingNum > 0) {\n group = this.data.substr(i)\n value = parseInt(group, 10)\n\n bitBuffer.put(value, remainingNum * 3 + 1)\n }\n}\n\nmodule.exports = NumericData\n","const Mode = require('./mode')\n\n/**\n * Array of characters available in alphanumeric mode\n *\n * As per QR Code specification, to each character\n * is assigned a value from 0 to 44 which in this case coincides\n * with the array index\n *\n * @type {Array}\n */\nconst ALPHA_NUM_CHARS = [\n '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\n 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',\n ' ', '$', '%', '*', '+', '-', '.', '/', ':'\n]\n\nfunction AlphanumericData (data) {\n this.mode = Mode.ALPHANUMERIC\n this.data = data\n}\n\nAlphanumericData.getBitsLength = function getBitsLength (length) {\n return 11 * Math.floor(length / 2) + 6 * (length % 2)\n}\n\nAlphanumericData.prototype.getLength = function getLength () {\n return this.data.length\n}\n\nAlphanumericData.prototype.getBitsLength = function getBitsLength () {\n return AlphanumericData.getBitsLength(this.data.length)\n}\n\nAlphanumericData.prototype.write = function write (bitBuffer) {\n let i\n\n // Input data characters are divided into groups of two characters\n // and encoded as 11-bit binary codes.\n for (i = 0; i + 2 <= this.data.length; i += 2) {\n // The character value of the first character is multiplied by 45\n let value = ALPHA_NUM_CHARS.indexOf(this.data[i]) * 45\n\n // The character value of the second digit is added to the product\n value += ALPHA_NUM_CHARS.indexOf(this.data[i + 1])\n\n // The sum is then stored as 11-bit binary number\n bitBuffer.put(value, 11)\n }\n\n // If the number of input data characters is not a multiple of two,\n // the character value of the final character is encoded as a 6-bit binary number.\n if (this.data.length % 2) {\n bitBuffer.put(ALPHA_NUM_CHARS.indexOf(this.data[i]), 6)\n }\n}\n\nmodule.exports = AlphanumericData\n","const Mode = require('./mode')\n\nfunction ByteData (data) {\n this.mode = Mode.BYTE\n if (typeof (data) === 'string') {\n this.data = new TextEncoder().encode(data)\n } else {\n this.data = new Uint8Array(data)\n }\n}\n\nByteData.getBitsLength = function getBitsLength (length) {\n return length * 8\n}\n\nByteData.prototype.getLength = function getLength () {\n return this.data.length\n}\n\nByteData.prototype.getBitsLength = function getBitsLength () {\n return ByteData.getBitsLength(this.data.length)\n}\n\nByteData.prototype.write = function (bitBuffer) {\n for (let i = 0, l = this.data.length; i < l; i++) {\n bitBuffer.put(this.data[i], 8)\n }\n}\n\nmodule.exports = ByteData\n","const Mode = require('./mode')\nconst Utils = require('./utils')\n\nfunction KanjiData (data) {\n this.mode = Mode.KANJI\n this.data = data\n}\n\nKanjiData.getBitsLength = function getBitsLength (length) {\n return length * 13\n}\n\nKanjiData.prototype.getLength = function getLength () {\n return this.data.length\n}\n\nKanjiData.prototype.getBitsLength = function getBitsLength () {\n return KanjiData.getBitsLength(this.data.length)\n}\n\nKanjiData.prototype.write = function (bitBuffer) {\n let i\n\n // In the Shift JIS system, Kanji characters are represented by a two byte combination.\n // These byte values are shifted from the JIS X 0208 values.\n // JIS X 0208 gives details of the shift coded representation.\n for (i = 0; i < this.data.length; i++) {\n let value = Utils.toSJIS(this.data[i])\n\n // For characters with Shift JIS values from 0x8140 to 0x9FFC:\n if (value >= 0x8140 && value <= 0x9FFC) {\n // Subtract 0x8140 from Shift JIS value\n value -= 0x8140\n\n // For characters with Shift JIS values from 0xE040 to 0xEBBF\n } else if (value >= 0xE040 && value <= 0xEBBF) {\n // Subtract 0xC140 from Shift JIS value\n value -= 0xC140\n } else {\n throw new Error(\n 'Invalid SJIS character: ' + this.data[i] + '\\n' +\n 'Make sure your charset is UTF-8')\n }\n\n // Multiply most significant byte of result by 0xC0\n // and add least significant byte to product\n value = (((value >>> 8) & 0xff) * 0xC0) + (value & 0xff)\n\n // Convert result to a 13-bit binary string\n bitBuffer.put(value, 13)\n }\n}\n\nmodule.exports = KanjiData\n","'use strict';\n\n/******************************************************************************\n * Created 2008-08-19.\n *\n * Dijkstra path-finding functions. Adapted from the Dijkstar Python project.\n *\n * Copyright (C) 2008\n * Wyatt Baldwin <self@wyattbaldwin.com>\n * All rights reserved\n *\n * Licensed under the MIT license.\n *\n * http://www.opensource.org/licenses/mit-license.php\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *****************************************************************************/\nvar dijkstra = {\n single_source_shortest_paths: function(graph, s, d) {\n // Predecessor map for each node that has been encountered.\n // node ID => predecessor node ID\n var predecessors = {};\n\n // Costs of shortest paths from s to all nodes encountered.\n // node ID => cost\n var costs = {};\n costs[s] = 0;\n\n // Costs of shortest paths from s to all nodes encountered; differs from\n // `costs` in that it provides easy access to the node that currently has\n // the known shortest path from s.\n // XXX: Do we actually need both `costs` and `open`?\n var open = dijkstra.PriorityQueue.make();\n open.push(s, 0);\n\n var closest,\n u, v,\n cost_of_s_to_u,\n adjacent_nodes,\n cost_of_e,\n cost_of_s_to_u_plus_cost_of_e,\n cost_of_s_to_v,\n first_visit;\n while (!open.empty()) {\n // In the nodes remaining in graph that have a known cost from s,\n // find the node, u, that currently has the shortest path from s.\n closest = open.pop();\n u = closest.value;\n cost_of_s_to_u = closest.cost;\n\n // Get nodes adjacent to u...\n adjacent_nodes = graph[u] || {};\n\n // ...and explore the edges that connect u to those nodes, updating\n // the cost of the shortest paths to any or all of those nodes as\n // necessary. v is the node across the current edge from u.\n for (v in adjacent_nodes) {\n if (adjacent_nodes.hasOwnProperty(v)) {\n // Get the cost of the edge running from u to v.\n cost_of_e = adjacent_nodes[v];\n\n // Cost of s to u plus the cost of u to v across e--this is *a*\n // cost from s to v that may or may not be less than the current\n // known cost to v.\n cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e;\n\n // If we haven't visited v yet OR if the current known cost from s to\n // v is greater than the new cost we just found (cost of s to u plus\n // cost of u to v across e), update v's cost in the cost list and\n // update v's predecessor in the predecessor list (it's now u).\n cost_of_s_to_v = costs[v];\n first_visit = (typeof costs[v] === 'undefined');\n if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) {\n costs[v] = cost_of_s_to_u_plus_cost_of_e;\n open.push(v, cost_of_s_to_u_plus_cost_of_e);\n predecessors[v] = u;\n }\n }\n }\n }\n\n if (typeof d !== 'undefined' && typeof costs[d] === 'undefined') {\n var msg = ['Could not find a path from ', s, ' to ', d, '.'].join('');\n throw new Error(msg);\n }\n\n return predecessors;\n },\n\n extract_shortest_path_from_predecessor_list: function(predecessors, d) {\n var nodes = [];\n var u = d;\n var predecessor;\n while (u) {\n nodes.push(u);\n predecessor = predecessors[u];\n u = predecessors[u];\n }\n nodes.reverse();\n return nodes;\n },\n\n find_path: function(graph, s, d) {\n var predecessors = dijkstra.single_source_shortest_paths(graph, s, d);\n return dijkstra.extract_shortest_path_from_predecessor_list(\n predecessors, d);\n },\n\n /**\n * A very naive priority queue implementation.\n */\n PriorityQueue: {\n make: function (opts) {\n var T = dijkstra.PriorityQueue,\n t = {},\n key;\n opts = opts || {};\n for (key in T) {\n if (T.hasOwnProperty(key)) {\n t[key] = T[key];\n }\n }\n t.queue = [];\n t.sorter = opts.sorter || T.default_sorter;\n return t;\n },\n\n default_sorter: function (a, b) {\n return a.cost - b.cost;\n },\n\n /**\n * Add a new item to the queue and ensure the highest priority element\n * is at the front of the queue.\n */\n push: function (value, cost) {\n var item = {value: value, cost: cost};\n this.queue.push(item);\n this.queue.sort(this.sorter);\n },\n\n /**\n * Return the highest priority element in the queue.\n */\n pop: function () {\n return this.queue.shift();\n },\n\n empty: function () {\n return this.queue.length === 0;\n }\n }\n};\n\n\n// node.js module exports\nif (typeof module !== 'undefined') {\n module.exports = dijkstra;\n}\n","const Mode = require('./mode')\nconst NumericData = require('./numeric-data')\nconst AlphanumericData = require('./alphanumeric-data')\nconst ByteData = require('./byte-data')\nconst KanjiData = require('./kanji-data')\nconst Regex = require('./regex')\nconst Utils = require('./utils')\nconst dijkstra = require('dijkstrajs')\n\n/**\n * Returns UTF8 byte length\n *\n * @param {String} str Input string\n * @return {Number} Number of byte\n */\nfunction getStringByteLength (str) {\n return unescape(encodeURIComponent(str)).length\n}\n\n/**\n * Get a list of segments of the specified mode\n * from a string\n *\n * @param {Mode} mode Segment mode\n * @param {String} str String to process\n * @return {Array} Array of object with segments data\n */\nfunction getSegments (regex, mode, str) {\n const segments = []\n let result\n\n while ((result = regex.exec(str)) !== null) {\n segments.push({\n data: result[0],\n index: result.index,\n mode: mode,\n length: result[0].length\n })\n }\n\n return segments\n}\n\n/**\n * Extracts a series of segments with the appropriate\n * modes from a string\n *\n * @param {String} dataStr Input string\n * @return {Array} Array of object with segments data\n */\nfunction getSegmentsFromString (dataStr) {\n const numSegs = getSegments(Regex.NUMERIC, Mode.NUMERIC, dataStr)\n const alphaNumSegs = getSegments(Regex.ALPHANUMERIC, Mode.ALPHANUMERIC, dataStr)\n let byteSegs\n let kanjiSegs\n\n if (Utils.isKanjiModeEnabled()) {\n byteSegs = getSegments(Regex.BYTE, Mode.BYTE, dataStr)\n kanjiSegs = getSegments(Regex.KANJI, Mode.KANJI, dataStr)\n } else {\n byteSegs = getSegments(Regex.BYTE_KANJI, Mode.BYTE, dataStr)\n kanjiSegs = []\n }\n\n const segs = numSegs.concat(alphaNumSegs, byteSegs, kanjiSegs)\n\n return segs\n .sort(function (s1, s2) {\n return s1.index - s2.index\n })\n .map(function (obj) {\n return {\n data: obj.data,\n mode: obj.mode,\n length: obj.length\n }\n })\n}\n\n/**\n * Returns how many bits are needed to encode a string of\n * specified length with the specified mode\n *\n * @param {Number} length String length\n * @param {Mode} mode Segment mode\n * @return {Number} Bit length\n */\nfunction getSegmentBitsLength (length, mode) {\n switch (mode) {\n case Mode.NUMERIC:\n return NumericData.getBitsLength(length)\n case Mode.ALPHANUMERIC:\n return AlphanumericData.getBitsLength(length)\n case Mode.KANJI:\n return KanjiData.getBitsLength(length)\n case Mode.BYTE:\n return ByteData.getBitsLength(length)\n }\n}\n\n/**\n * Merges adjacent segments which have the same mode\n *\n * @param {Array} segs Array of object with segments data\n * @return {Array} Array of object with segments data\n */\nfunction mergeSegments (segs) {\n return segs.reduce(function (acc, curr) {\n const prevSeg = acc.length - 1 >= 0 ? acc[acc.length - 1] : null\n if (prevSeg && prevSeg.mode === curr.mode) {\n acc[acc.length - 1].data += curr.data\n return acc\n }\n\n acc.push(curr)\n return acc\n }, [])\n}\n\n/**\n * Generates a list of all possible nodes combination which\n * will be used to build a segments graph.\n *\n * Nodes are divided by groups. Each group will contain a list of all the modes\n * in which is possible to encode the given text.\n *\n * For example the text '12345' can be encoded as Numeric, Alphanumeric or Byte.\n * The group for '12345' will contain then 3 objects, one for each\n * possible encoding mode.\n *\n * Each node represents a possible segment.\n *\n * @param {Array} segs Array of object with segments data\n * @return {Array} Array of object with segments data\n */\nfunction buildNodes (segs) {\n const nodes = []\n for (let i = 0; i < segs.length; i++) {\n const seg = segs[i]\n\n switch (seg.mode) {\n case Mode.NUMERIC:\n nodes.push([seg,\n { data: seg.data, mode: Mode.ALPHANUMERIC, length: seg.length },\n { data: seg.data, mode: Mode.BYTE, length: seg.length }\n ])\n break\n case Mode.ALPHANUMERIC:\n nodes.push([seg,\n { data: seg.data, mode: Mode.BYTE, length: seg.length }\n ])\n break\n case Mode.KANJI:\n nodes.push([seg,\n { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }\n ])\n break\n case Mode.BYTE:\n nodes.push([\n { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }\n ])\n }\n }\n\n return nodes\n}\n\n/**\n * Builds a graph from a list of nodes.\n * All segments in each node group will be connected with all the segments of\n * the next group and so on.\n *\n * At each connection will be assigned a weight depending on the\n * segment's byte length.\n *\n * @param {Array} nodes Array of object with segments data\n * @param {Number} version QR Code version\n * @return {Object} Graph of all possible segments\n */\nfunction buildGraph (nodes, version) {\n const table = {}\n const graph = { start: {} }\n let prevNodeIds = ['start']\n\n for (let i = 0; i < nodes.length; i++) {\n const nodeGroup = nodes[i]\n const currentNodeIds = []\n\n for (let j = 0; j < nodeGroup.length; j++) {\n const node = nodeGroup[j]\n const key = '' + i + j\n\n currentNodeIds.push(key)\n table[key] = { node: node, lastCount: 0 }\n graph[key] = {}\n\n for (let n = 0; n < prevNodeIds.length; n++) {\n const prevNodeId = prevNodeIds[n]\n\n if (table[prevNodeId] && table[prevNodeId].node.mode === node.mode) {\n graph[prevNodeId][key] =\n getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) -\n getSegmentBitsLength(table[prevNodeId].lastCount, node.mode)\n\n table[prevNodeId].lastCount += node.length\n } else {\n if (table[prevNodeId]) table[prevNodeId].lastCount = node.length\n\n graph[prevNodeId][key] = getSegmentBitsLength(node.length, node.mode) +\n 4 + Mode.getCharCountIndicator(node.mode, version) // switch cost\n }\n }\n }\n\n prevNodeIds = currentNodeIds\n }\n\n for (let n = 0; n < prevNodeIds.length; n++) {\n graph[prevNodeIds[n]].end = 0\n }\n\n return { map: graph, table: table }\n}\n\n/**\n * Builds a segment from a specified data and mode.\n * If a mode is not specified, the more suitable will be used.\n *\n * @param {String} data Input data\n * @param {Mode | String} modesHint Data mode\n * @return {Segment} Segment\n */\nfunction buildSingleSegment (data, modesHint) {\n let mode\n const bestMode = Mode.getBestModeForData(data)\n\n mode = Mode.from(modesHint, bestMode)\n\n // Make sure data can be encoded\n if (mode !== Mode.BYTE && mode.bit < bestMode.bit) {\n throw new Error('\"' + data + '\"' +\n ' cannot be encoded with mode ' + Mode.toString(mode) +\n '.\\n Suggested mode is: ' + Mode.toString(bestMode))\n }\n\n // Use Mode.BYTE if Kanji support is disabled\n if (mode === Mode.KANJI && !Utils.isKanjiModeEnabled()) {\n mode = Mode.BYTE\n }\n\n switch (mode) {\n case Mode.NUMERIC:\n return new NumericData(data)\n\n case Mode.ALPHANUMERIC:\n return new AlphanumericData(data)\n\n case Mode.KANJI:\n return new KanjiData(data)\n\n case Mode.BYTE:\n return new ByteData(data)\n }\n}\n\n/**\n * Builds a list of segments from an array.\n * Array can contain Strings or Objects with segment's info.\n *\n * For each item which is a string, will be generated a segment with the given\n * string and the more appropriate encoding mode.\n *\n * For each item which is an object, will be generated a segment with the given\n * data and mode.\n * Objects must contain at least the property \"data\".\n * If property \"mode\" is not present, the more suitable mode will be used.\n *\n * @param {Array} array Array of objects with segments data\n * @return {Array} Array of Segments\n */\nexports.fromArray = function fromArray (array) {\n return array.reduce(function (acc, seg) {\n if (typeof seg === 'string') {\n acc.push(buildSingleSegment(seg, null))\n } else if (seg.data) {\n acc.push(buildSingleSegment(seg.data, seg.mode))\n }\n\n return acc\n }, [])\n}\n\n/**\n * Builds an optimized sequence of segments from a string,\n * which will produce the shortest possible bitstream.\n *\n * @param {String} data Input string\n * @param {Number} version QR Code version\n * @return {Array} Array of segments\n */\nexports.fromString = function fromString (data, version) {\n const segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled())\n\n const nodes = buildNodes(segs)\n const graph = buildGraph(nodes, version)\n const path = dijkstra.find_path(graph.map, 'start', 'end')\n\n const optimizedSegs = []\n for (let i = 1; i < path.length - 1; i++) {\n optimizedSegs.push(graph.table[path[i]].node)\n }\n\n return exports.fromArray(mergeSegments(optimizedSegs))\n}\n\n/**\n * Splits a string in various segments with the modes which\n * best represent their content.\n * The produced segments are far from being optimized.\n * The output of this function is only used to estimate a QR Code version\n * which may contain the data.\n *\n * @param {string} data Input string\n * @return {Array} Array of segments\n */\nexports.rawSplit = function rawSplit (data) {\n return exports.fromArray(\n getSegmentsFromString(data, Utils.isKanjiModeEnabled())\n )\n}\n","const Utils = require('./utils')\nconst ECLevel = require('./error-correction-level')\nconst BitBuffer = require('./bit-buffer')\nconst BitMatrix = require('./bit-matrix')\nconst AlignmentPattern = require('./alignment-pattern')\nconst FinderPattern = require('./finder-pattern')\nconst MaskPattern = require('./mask-pattern')\nconst ECCode = require('./error-correction-code')\nconst ReedSolomonEncoder = require('./reed-solomon-encoder')\nconst Version = require('./version')\nconst FormatInfo = require('./format-info')\nconst Mode = require('./mode')\nconst Segments = require('./segments')\n\n/**\n * QRCode for JavaScript\n *\n * modified by Ryan Day for nodejs support\n * Copyright (c) 2011 Ryan Day\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/mit-license.php\n *\n//---------------------------------------------------------------------\n// QRCode for JavaScript\n//\n// Copyright (c) 2009 Kazuhiko Arase\n//\n// URL: http://www.d-project.com/\n//\n// Licensed under the MIT license:\n// http://www.opensource.org/licenses/mit-license.php\n//\n// The word \"QR Code\" is registered trademark of\n// DENSO WAVE INCORPORATED\n// http://www.denso-wave.com/qrcode/faqpatent-e.html\n//\n//---------------------------------------------------------------------\n*/\n\n/**\n * Add finder patterns bits to matrix\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {Number} version QR Code version\n */\nfunction setupFinderPattern (matrix, version) {\n const size = matrix.size\n const pos = FinderPattern.getPositions(version)\n\n for (let i = 0; i < pos.length; i++) {\n const row = pos[i][0]\n const col = pos[i][1]\n\n for (let r = -1; r <= 7; r++) {\n if (row + r <= -1 || size <= row + r) continue\n\n for (let c = -1; c <= 7; c++) {\n if (col + c <= -1 || size <= col + c) continue\n\n if ((r >= 0 && r <= 6 && (c === 0 || c === 6)) ||\n (c >= 0 && c <= 6 && (r === 0 || r === 6)) ||\n (r >= 2 && r <= 4 && c >= 2 && c <= 4)) {\n matrix.set(row + r, col + c, true, true)\n } else {\n matrix.set(row + r, col + c, false, true)\n }\n }\n }\n }\n}\n\n/**\n * Add timing pattern bits to matrix\n *\n * Note: this function must be called before {@link setupAlignmentPattern}\n *\n * @param {BitMatrix} matrix Modules matrix\n */\nfunction setupTimingPattern (matrix) {\n const size = matrix.size\n\n for (let r = 8; r < size - 8; r++) {\n const value = r % 2 === 0\n matrix.set(r, 6, value, true)\n matrix.set(6, r, value, true)\n }\n}\n\n/**\n * Add alignment patterns bits to matrix\n *\n * Note: this function must be called after {@link setupTimingPattern}\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {Number} version QR Code version\n */\nfunction setupAlignmentPattern (matrix, version) {\n const pos = AlignmentPattern.getPositions(version)\n\n for (let i = 0; i < pos.length; i++) {\n const row = pos[i][0]\n const col = pos[i][1]\n\n for (let r = -2; r <= 2; r++) {\n for (let c = -2; c <= 2; c++) {\n if (r === -2 || r === 2 || c === -2 || c === 2 ||\n (r === 0 && c === 0)) {\n matrix.set(row + r, col + c, true, true)\n } else {\n matrix.set(row + r, col + c, false, true)\n }\n }\n }\n }\n}\n\n/**\n * Add version info bits to matrix\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {Number} version QR Code version\n */\nfunction setupVersionInfo (matrix, version) {\n const size = matrix.size\n const bits = Version.getEncodedBits(version)\n let row, col, mod\n\n for (let i = 0; i < 18; i++) {\n row = Math.floor(i / 3)\n col = i % 3 + size - 8 - 3\n mod = ((bits >> i) & 1) === 1\n\n matrix.set(row, col, mod, true)\n matrix.set(col, row, mod, true)\n }\n}\n\n/**\n * Add format info bits to matrix\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level\n * @param {Number} maskPattern Mask pattern reference value\n */\nfunction setupFormatInfo (matrix, errorCorrectionLevel, maskPattern) {\n const size = matrix.size\n const bits = FormatInfo.getEncodedBits(errorCorrectionLevel, maskPattern)\n let i, mod\n\n for (i = 0; i < 15; i++) {\n mod = ((bits >> i) & 1) === 1\n\n // vertical\n if (i < 6) {\n matrix.set(i, 8, mod, true)\n } else if (i < 8) {\n matrix.set(i + 1, 8, mod, true)\n } else {\n matrix.set(size - 15 + i, 8, mod, true)\n }\n\n // horizontal\n if (i < 8) {\n matrix.set(8, size - i - 1, mod, true)\n } else if (i < 9) {\n matrix.set(8, 15 - i - 1 + 1, mod, true)\n } else {\n matrix.set(8, 15 - i - 1, mod, true)\n }\n }\n\n // fixed module\n matrix.set(size - 8, 8, 1, true)\n}\n\n/**\n * Add encoded data bits to matrix\n *\n * @param {BitMatrix} matrix Modules matrix\n * @param {Uint8Array} data Data codewords\n */\nfunction setupData (matrix, data) {\n const size = matrix.size\n let inc = -1\n let row = size - 1\n let bitIndex = 7\n let byteIndex = 0\n\n for (let col = size - 1; col > 0; col -= 2) {\n if (col === 6) col--\n\n while (true) {\n for (let c = 0; c < 2; c++) {\n if (!matrix.isReserved(row, col - c)) {\n let dark = false\n\n if (byteIndex < data.length) {\n dark = (((data[byteIndex] >>> bitIndex) & 1) === 1)\n }\n\n matrix.set(row, col - c, dark)\n bitIndex--\n\n if (bitIndex === -1) {\n byteIndex++\n bitIndex = 7\n }\n }\n }\n\n row += inc\n\n if (row < 0 || size <= row) {\n row -= inc\n inc = -inc\n break\n }\n }\n }\n}\n\n/**\n * Create encoded codewords from data input\n *\n * @param {Number} version QR Code version\n * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level\n * @param {ByteData} data Data input\n * @return {Uint8Array} Buffer containing encoded codewords\n */\nfunction createData (version, errorCorrectionLevel, segments) {\n // Prepare data buffer\n const buffer = new BitBuffer()\n\n segments.forEach(function (data) {\n // prefix data with mode indicator (4 bits)\n buffer.put(data.mode.bit, 4)\n\n // Prefix data with character count indicator.\n // The character count indicator is a string of bits that represents the\n // number of characters that are being encoded.\n // The character count indicator must be placed after the mode indicator\n // and must be a certain number of bits long, depending on the QR version\n // and data mode\n // @see {@link Mode.getCharCountIndicator}.\n buffer.put(data.getLength(), Mode.getCharCountIndicator(data.mode, version))\n\n // add binary data sequence to buffer\n data.write(buffer)\n })\n\n // Calculate required number of bits\n const totalCodewords = Utils.getSymbolTotalCodewords(version)\n const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)\n const dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8\n\n // Add a terminator.\n // If the bit string is shorter than the total number of required bits,\n // a terminator of up to four 0s must be added to the right side of the string.\n // If the bit string is more than four bits shorter than the required number of bits,\n // add four 0s to the end.\n if (buffer.getLengthInBits() + 4 <= dataTotalCodewordsBits) {\n buffer.put(0, 4)\n }\n\n // If the bit string is fewer than four bits shorter, add only the number of 0s that\n // are needed to reach the required number of bits.\n\n // After adding the terminator, if the number of bits in the string is not a multiple of 8,\n // pad the string on the right with 0s to make the string's length a multiple of 8.\n while (buffer.getLengthInBits() % 8 !== 0) {\n buffer.putBit(0)\n }\n\n // Add pad bytes if the string is still shorter than the total number of required bits.\n // Extend the buffer to fill the data capacity of the symbol corresponding to\n // the Version and Error Correction Level by adding the Pad Codewords 11101100 (0xEC)\n // and 00010001 (0x11) alternately.\n const remainingByte = (dataTotalCodewordsBits - buffer.getLengthInBits()) / 8\n for (let i = 0; i < remainingByte; i++) {\n buffer.put(i % 2 ? 0x11 : 0xEC, 8)\n }\n\n return createCodewords(buffer, version, errorCorrectionLevel)\n}\n\n/**\n * Encode input data with Reed-Solomon and return codewords with\n * relative error correction bits\n *\n * @param {BitBuffer} bitBuffer Data to encode\n * @param {Number} version QR Code version\n * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level\n * @return {Uint8Array} Buffer containing encoded codewords\n */\nfunction createCodewords (bitBuffer, version, errorCorrectionLevel) {\n // Total codewords for this QR code version (Data + Error correction)\n const totalCodewords = Utils.getSymbolTotalCodewords(version)\n\n // Total number of error correction codewords\n const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)\n\n // Total number of data codewords\n const dataTotalCodewords = totalCodewords - ecTotalCodewords\n\n // Total number of blocks\n const ecTotalBlocks = ECCode.getBlocksCount(version, errorCorrectionLevel)\n\n // Calculate how many blocks each group should contain\n const blocksInGroup2 = totalCodewords % ecTotalBlocks\n const blocksInGroup1 = ecTotalBlocks - blocksInGroup2\n\n const totalCodewordsInGroup1 = Math.floor(totalCodewords / ecTotalBlocks)\n\n const dataCodewordsInGroup1 = Math.floor(dataTotalCodewords / ecTotalBlocks)\n const dataCodewordsInGroup2 = dataCodewordsInGroup1 + 1\n\n // Number of EC codewords is the same for both groups\n const ecCount = totalCodewordsInGroup1 - dataCodewordsInGroup1\n\n // Initialize a Reed-Solomon encoder with a generator polynomial of degree ecCount\n const rs = new ReedSolomonEncoder(ecCount)\n\n let offset = 0\n const dcData = new Array(ecTotalBlocks)\n const ecData = new Array(ecTotalBlocks)\n let maxDataSize = 0\n const buffer = new Uint8Array(bitBuffer.buffer)\n\n // Divide the buffer into the required number of blocks\n for (let b = 0; b < ecTotalBlocks; b++) {\n const dataSize = b < blocksInGroup1 ? dataCodewordsInGroup1 : dataCodewordsInGroup2\n\n // extract a block of data from buffer\n dcData[b] = buffer.slice(offset, offset + dataSize)\n\n // Calculate EC codewords for this data block\n ecData[b] = rs.encode(dcData[b])\n\n offset += dataSize\n maxDataSize = Math.max(maxDataSize, dataSize)\n }\n\n // Create final data\n // Interleave the data and error correction codewords from each block\n const data = new Uint8Array(totalCodewords)\n let index = 0\n let i, r\n\n // Add data codewords\n for (i = 0; i < maxDataSize; i++) {\n for (r = 0; r < ecTotalBlocks; r++) {\n if (i < dcData[r].length) {\n data[index++] = dcData[r][i]\n }\n }\n }\n\n // Apped EC codewords\n for (i = 0; i < ecCount; i++) {\n for (r = 0; r < ecTotalBlocks; r++) {\n data[index++] = ecData[r][i]\n }\n }\n\n return data\n}\n\n/**\n * Build QR Code symbol\n *\n * @param {String} data Input string\n * @param {Number} version QR Code version\n * @param {ErrorCorretionLevel} errorCorrectionLevel Error level\n * @param {MaskPattern} maskPattern Mask pattern\n * @return {Object} Object containing symbol data\n */\nfunction createSymbol (data, version, errorCorrectionLevel, maskPattern) {\n let segments\n\n if (Array.isArray(data)) {\n segments = Segments.fromArray(data)\n } else if (typeof data === 'string') {\n let estimatedVersion = version\n\n if (!estimatedVersion) {\n const rawSegments = Segments.rawSplit(data)\n\n // Estimate best version that can contain raw splitted segments\n estimatedVersion = Version.getBestVersionForData(rawSegments, errorCorrectionLevel)\n }\n\n // Build optimized segments\n // If estimated version is undefined, try with the highest version\n segments = Segments.fromString(data, estimatedVersion || 40)\n } else {\n throw new Error('Invalid data')\n }\n\n // Get the min version that can contain data\n const bestVersion = Version.getBestVersionForData(segments, errorCorrectionLevel)\n\n // If no version is found, data cannot be stored\n if (!bestVersion) {\n throw new Error('The amount of data is too big to be stored in a QR Code')\n }\n\n // If not specified, use min version as default\n if (!version) {\n version = bestVersion\n\n // Check if the specified version can contain the data\n } else if (version < bestVersion) {\n throw new Error('\\n' +\n 'The chosen QR Code version cannot contain this amount of data.\\n' +\n 'Minimum version required to store current data is: ' + bestVersion + '.\\n'\n )\n }\n\n const dataBits = createData(version, errorCorrectionLevel, segments)\n\n // Allocate matrix buffer\n const moduleCount = Utils.getSymbolSize(version)\n const modules = new BitMatrix(moduleCount)\n\n // Add function modules\n setupFinderPattern(modules, version)\n setupTimingPattern(modules)\n setupAlignmentPattern(modules, version)\n\n // Add temporary dummy bits for format info just to set them as reserved.\n // This is needed to prevent these bits from being masked by {@link MaskPattern.applyMask}\n // since the masking operation must be performed only on the encoding region.\n // These blocks will be replaced with correct values later in code.\n setupFormatInfo(modules, errorCorrectionLevel, 0)\n\n if (version >= 7) {\n setupVersionInfo(modules, version)\n }\n\n // Add data codewords\n setupData(modules, dataBits)\n\n if (isNaN(maskPattern)) {\n // Find best mask pattern\n maskPattern = MaskPattern.getBestMask(modules,\n setupFormatInfo.bind(null, modules, errorCorrectionLevel))\n }\n\n // Apply mask pattern\n MaskPattern.applyMask(maskPattern, modules)\n\n // Replace format info bits with correct values\n setupFormatInfo(modules, errorCorrectionLevel, maskPattern)\n\n return {\n modules: modules,\n version: version,\n errorCorrectionLevel: errorCorrectionLevel,\n maskPattern: maskPattern,\n segments: segments\n }\n}\n\n/**\n * QR Code\n *\n * @param {String | Array} data Input data\n * @param {Object} options Optional configurations\n * @param {Number} options.version QR Code version\n * @param {String} options.errorCorrectionLevel Error correction level\n * @param {Function} options.toSJISFunc Helper func to convert utf8 to sjis\n */\nexports.create = function create (data, options) {\n if (typeof data === 'undefined' || data === '') {\n throw new Error('No input text')\n }\n\n let errorCorrectionLevel = ECLevel.M\n let version\n let mask\n\n if (typeof options !== 'undefined') {\n // Use higher error correction level as default\n errorCorrectionLevel = ECLevel.from(options.errorCorrectionLevel, ECLevel.M)\n version = Version.from(options.version)\n mask = MaskPattern.from(options.maskPattern)\n\n if (options.toSJISFunc) {\n Utils.setToSJISFunction(options.toSJISFunc)\n }\n }\n\n return createSymbol(data, version, errorCorrectionLevel, mask)\n}\n","function hex2rgba (hex) {\n if (typeof hex === 'number') {\n hex = hex.toString()\n }\n\n if (typeof hex !== 'string') {\n throw new Error('Color should be defined as hex string')\n }\n\n let hexCode = hex.slice().replace('#', '').split('')\n if (hexCode.length < 3 || hexCode.length === 5 || hexCode.length > 8) {\n throw new Error('Invalid hex color: ' + hex)\n }\n\n // Convert from short to long form (fff -> ffffff)\n if (hexCode.length === 3 || hexCode.length === 4) {\n hexCode = Array.prototype.concat.apply([], hexCode.map(function (c) {\n return [c, c]\n }))\n }\n\n // Add default alpha value\n if (hexCode.length === 6) hexCode.push('F', 'F')\n\n const hexValue = parseInt(hexCode.join(''), 16)\n\n return {\n r: (hexValue >> 24) & 255,\n g: (hexValue >> 16) & 255,\n b: (hexValue >> 8) & 255,\n a: hexValue & 255,\n hex: '#' + hexCode.slice(0, 6).join('')\n }\n}\n\nexports.getOptions = function getOptions (options) {\n if (!options) options = {}\n if (!options.color) options.color = {}\n\n const margin = typeof options.margin === 'undefined' ||\n options.margin === null ||\n options.margin < 0\n ? 4\n : options.margin\n\n const width = options.width && options.width >= 21 ? options.width : undefined\n const scale = options.scale || 4\n\n return {\n width: width,\n scale: width ? 4 : scale,\n margin: margin,\n color: {\n dark: hex2rgba(options.color.dark || '#000000ff'),\n light: hex2rgba(options.color.light || '#ffffffff')\n },\n type: options.type,\n rendererOpts: options.rendererOpts || {}\n }\n}\n\nexports.getScale = function getScale (qrSize, opts) {\n return opts.width && opts.width >= qrSize + opts.margin * 2\n ? opts.width / (qrSize + opts.margin * 2)\n : opts.scale\n}\n\nexports.getImageWidth = function getImageWidth (qrSize, opts) {\n const scale = exports.getScale(qrSize, opts)\n return Math.floor((qrSize + opts.margin * 2) * scale)\n}\n\nexports.qrToImageData = function qrToImageData (imgData, qr, opts) {\n const size = qr.modules.size\n const data = qr.modules.data\n const scale = exports.getScale(size, opts)\n const symbolSize = Math.floor((size + opts.margin * 2) * scale)\n const scaledMargin = opts.margin * scale\n const palette = [opts.color.light, opts.color.dark]\n\n for (let i = 0; i < symbolSize; i++) {\n for (let j = 0; j < symbolSize; j++) {\n let posDst = (i * symbolSize + j) * 4\n let pxColor = opts.color.light\n\n if (i >= scaledMargin && j >= scaledMargin &&\n i < symbolSize - scaledMargin && j < symbolSize - scaledMargin) {\n const iSrc = Math.floor((i - scaledMargin) / scale)\n const jSrc = Math.floor((j - scaledMargin) / scale)\n pxColor = palette[data[iSrc * size + jSrc] ? 1 : 0]\n }\n\n imgData[posDst++] = pxColor.r\n imgData[posDst++] = pxColor.g\n imgData[posDst++] = pxColor.b\n imgData[posDst] = pxColor.a\n }\n }\n}\n","const Utils = require('./utils')\n\nfunction clearCanvas (ctx, canvas, size) {\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n if (!canvas.style) canvas.style = {}\n canvas.height = size\n canvas.width = size\n canvas.style.height = size + 'px'\n canvas.style.width = size + 'px'\n}\n\nfunction getCanvasElement () {\n try {\n return document.createElement('canvas')\n } catch (e) {\n throw new Error('You need to specify a canvas element')\n }\n}\n\nexports.render = function render (qrData, canvas, options) {\n let opts = options\n let canvasEl = canvas\n\n if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {\n opts = canvas\n canvas = undefined\n }\n\n if (!canvas) {\n canvasEl = getCanvasElement()\n }\n\n opts = Utils.getOptions(opts)\n const size = Utils.getImageWidth(qrData.modules.size, opts)\n\n const ctx = canvasEl.getContext('2d')\n const image = ctx.createImageData(size, size)\n Utils.qrToImageData(image.data, qrData, opts)\n\n clearCanvas(ctx, canvasEl, size)\n ctx.putImageData(image, 0, 0)\n\n return canvasEl\n}\n\nexports.renderToDataURL = function renderToDataURL (qrData, canvas, options) {\n let opts = options\n\n if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {\n opts = canvas\n canvas = undefined\n }\n\n if (!opts) opts = {}\n\n const canvasEl = exports.render(qrData, canvas, opts)\n\n const type = opts.type || 'image/png'\n const rendererOpts = opts.rendererOpts || {}\n\n return canvasEl.toDataURL(type, rendererOpts.quality)\n}\n","const Utils = require('./utils')\n\nfunction getColorAttrib (color, attrib) {\n const alpha = color.a / 255\n const str = attrib + '=\"' + color.hex + '\"'\n\n return alpha < 1\n ? str + ' ' + attrib + '-opacity=\"' + alpha.toFixed(2).slice(1) + '\"'\n : str\n}\n\nfunction svgCmd (cmd, x, y) {\n let str = cmd + x\n if (typeof y !== 'undefined') str += ' ' + y\n\n return str\n}\n\nfunction qrToPath (data, size, margin) {\n let path = ''\n let moveBy = 0\n let newRow = false\n let lineLength = 0\n\n for (let i = 0; i < data.length; i++) {\n const col = Math.floor(i % size)\n const row = Math.floor(i / size)\n\n if (!col && !newRow) newRow = true\n\n if (data[i]) {\n lineLength++\n\n if (!(i > 0 && col > 0 && data[i - 1])) {\n path += newRow\n ? svgCmd('M', col + margin, 0.5 + row + margin)\n : svgCmd('m', moveBy, 0)\n\n moveBy = 0\n newRow = false\n }\n\n if (!(col + 1 < size && data[i + 1])) {\n path += svgCmd('h', lineLength)\n lineLength = 0\n }\n } else {\n moveBy++\n }\n }\n\n return path\n}\n\nexports.render = function render (qrData, options, cb) {\n const opts = Utils.getOptions(options)\n const size = qrData.modules.size\n const data = qrData.modules.data\n const qrcodesize = size + opts.margin * 2\n\n const bg = !opts.color.light.a\n ? ''\n : '<path ' + getColorAttrib(opts.color.light, 'fill') +\n ' d=\"M0 0h' + qrcodesize + 'v' + qrcodesize + 'H0z\"/>'\n\n const path =\n '<path ' + getColorAttrib(opts.color.dark, 'stroke') +\n ' d=\"' + qrToPath(data, size, opts.margin) + '\"/>'\n\n const viewBox = 'viewBox=\"' + '0 0 ' + qrcodesize + ' ' + qrcodesize + '\"'\n\n const width = !opts.width ? '' : 'width=\"' + opts.width + '\" height=\"' + opts.width + '\" '\n\n const svgTag = '<svg xmlns=\"http://www.w3.org/2000/svg\" ' + width + viewBox + ' shape-rendering=\"crispEdges\">' + bg + path + '</svg>\\n'\n\n if (typeof cb === 'function') {\n cb(null, svgTag)\n }\n\n return svgTag\n}\n","\nconst canPromise = require('./can-promise')\n\nconst QRCode = require('./core/qrcode')\nconst CanvasRenderer = require('./renderer/canvas')\nconst SvgRenderer = require('./renderer/svg-tag.js')\n\nfunction renderCanvas (renderFunc, canvas, text, opts, cb) {\n const args = [].slice.call(arguments, 1)\n const argsNum = args.length\n const isLastArgCb = typeof args[argsNum - 1] === 'function'\n\n if (!isLastArgCb && !canPromise()) {\n throw new Error('Callback required as last argument')\n }\n\n if (isLastArgCb) {\n if (argsNum < 2) {\n throw new Error('Too few arguments provided')\n }\n\n if (argsNum === 2) {\n cb = text\n text = canvas\n canvas = opts = undefined\n } else if (argsNum === 3) {\n if (canvas.getContext && typeof cb === 'undefined') {\n cb = opts\n opts = undefined\n } else {\n cb = opts\n opts = text\n text = canvas\n canvas = undefined\n }\n }\n } else {\n if (argsNum < 1) {\n throw new Error('Too few arguments provided')\n }\n\n if (argsNum === 1) {\n text = canvas\n canvas = opts = undefined\n } else if (argsNum === 2 && !canvas.getContext) {\n opts = text\n text = canvas\n canvas = undefined\n }\n\n return new Promise(function (resolve, reject) {\n try {\n const data = QRCode.create(text, opts)\n resolve(renderFunc(data, canvas, opts))\n } catch (e) {\n reject(e)\n }\n })\n }\n\n try {\n const data = QRCode.create(text, opts)\n cb(null, renderFunc(data, canvas, opts))\n } catch (e) {\n cb(e)\n }\n}\n\nexports.create = QRCode.create\nexports.toCanvas = renderCanvas.bind(null, CanvasRenderer.render)\nexports.toDataURL = renderCanvas.bind(null, CanvasRenderer.renderToDataURL)\n\n// only svg for now.\nexports.toString = renderCanvas.bind(null, function (data, _, opts) {\n return SvgRenderer.render(data, opts)\n})\n","import type { PairingGrantSnapshot } from './report-wire.ts'\n\nexport const PAIRING_QR_TYPE = 'deeppilot-pairing'\nexport const PAIRING_QR_VERSION = 2\n\n/** `sha256:` + base64url(SHA-256(SubjectPublicKeyInfo DER)) of the LAN certificate. */\nexport const LAN_TLS_FINGERPRINT_PATTERN = /^sha256:[A-Za-z0-9_-]{43}$/\n\nexport function isLanTlsFingerprint(value: unknown): value is string {\n return typeof value === 'string' && LAN_TLS_FINGERPRINT_PATTERN.test(value)\n}\n\nexport interface PairingQRPayload {\n v: typeof PAIRING_QR_VERSION\n type: typeof PAIRING_QR_TYPE\n host: string\n code: string\n expiresAt: number\n audience: string\n /** Required for LAN hosts (self-signed TLS); absent for public-CA hosts. */\n tlsFingerprint?: string\n}\n\nexport interface PairingTarget {\n host: string\n kind: 'public' | 'lan'\n tlsFingerprint?: string\n}\n\n/**\n * Return every explicit DeepPilot transport target. LAN comes first because\n * it is private and lower latency; an online Funnel remains available as a\n * separate choice instead of silently replacing the local address. A LAN\n * listener without a certificate pin is never offered: the app could not\n * trust it.\n */\nexport function selectPairingTargets(\n local: { phase: string; endpoints: string[]; tlsFingerprint?: string },\n remote: { phase: string; publicURL?: string },\n): PairingTarget[] {\n const targets: PairingTarget[] = []\n if (local.phase === 'online' && isLanTlsFingerprint(local.tlsFingerprint)) {\n for (const host of local.endpoints) {\n if (validTargetHost(host)) targets.push({ host, kind: 'lan', tlsFingerprint: local.tlsFingerprint })\n }\n }\n if (remote.phase === 'online' && remote.publicURL && validTargetHost(remote.publicURL)) {\n targets.push({ host: remote.publicURL, kind: 'public' })\n }\n const seen = new Set<string>()\n return targets.filter(({ host }) => !seen.has(host) && seen.add(host))\n}\n\n/** Only encrypted transports are ever offered to the app. */\nconst TARGET_PROTOCOLS = ['https:', 'wss:']\n\nfunction validTargetHost(value: string): boolean {\n try {\n const parsed = new URL(value)\n return TARGET_PROTOCOLS.includes(parsed.protocol)\n && parsed.hostname !== ''\n && parsed.username === ''\n && parsed.password === ''\n } catch {\n return false\n }\n}\n\n/** Encode a short-lived, single-use pairing grant without URL credentials. */\nexport function encodePairingQRPayload(host: string, grant: PairingGrantSnapshot, tlsFingerprint?: string): string {\n assertPairingInput(host, grant, tlsFingerprint)\n const payload: PairingQRPayload = {\n v: PAIRING_QR_VERSION,\n type: PAIRING_QR_TYPE,\n host: host.trim(),\n code: grant.code.trim(),\n expiresAt: grant.expiresAt,\n audience: grant.audience,\n ...(tlsFingerprint !== undefined ? { tlsFingerprint } : {}),\n }\n return JSON.stringify(payload)\n}\n\n/**\n * One copyable string carrying everything the app needs to pair: host, the\n * single-use code, the LAN certificate pin and the host audience.\n *\n * Users copy this once instead of moving three separate values, and the app\n * accepts it from the paste field, a deep link and (from this version on) the\n * QR code. Field names are short because the whole string ends up in a QR code\n * and in a text field: `h` host, `c` code, `f` fingerprint, `a` audience,\n * `e` expiry in milliseconds.\n */\nexport function encodePairingLink(host: string, grant: PairingGrantSnapshot, tlsFingerprint?: string): string {\n assertPairingInput(host, grant, tlsFingerprint)\n const params = new URLSearchParams()\n params.set('h', host.trim())\n params.set('c', grant.code.trim())\n if (tlsFingerprint !== undefined) params.set('f', tlsFingerprint)\n params.set('a', grant.audience)\n params.set('e', String(grant.expiresAt))\n // URLSearchParams percent-encodes the host and the pin; the app decodes them.\n return `${PAIRING_LINK_PREFIX}?${params.toString()}`\n}\n\n/** `deeppilot://pair` — the deep-link route the iOS app parses. */\nexport const PAIRING_LINK_PREFIX = 'deeppilot://pair'\n\nfunction assertPairingInput(host: string, grant: PairingGrantSnapshot, tlsFingerprint?: string): void {\n if (!validTargetHost(host.trim())) {\n throw new TypeError('pairing QR requires a valid HTTPS/WSS host')\n }\n if (grant.code.trim().length < 32 || !Number.isInteger(grant.expiresAt) || grant.expiresAt <= Date.now()) {\n throw new TypeError('pairing grant is invalid or expired')\n }\n if (!grant.audience.startsWith('deeppilot:')) throw new TypeError('pairing audience is invalid')\n if (tlsFingerprint !== undefined && !isLanTlsFingerprint(tlsFingerprint)) {\n throw new TypeError('pairing TLS fingerprint is invalid')\n }\n}\n","import type { PairingTarget } from '../pairing-qr.ts'\nimport type { PairingGrantSnapshot } from '../report-wire.ts'\n\n/**\n * Pure state machine for the pairing panel on the plugin settings page.\n *\n * It lives outside the React component because the behaviour that used to be\n * wrong is exactly the kind a renderer cannot show in a unit test: switching\n * between the LAN and public address must keep the panel open and re-issue a\n * grant for the newly selected host instead of collapsing it.\n */\nexport interface PairingPanelState {\n /** Address the visible grant was issued for; null = panel closed. */\n target: PairingTarget | null\n busy: boolean\n grant: PairingGrantSnapshot | null\n link: string | null\n qrDataURL: string | null\n message: string\n /** Transient \"copied\" feedback; cleared after a moment. */\n notice: string\n /** Monotonic id; only the newest in-flight issue may render a result. */\n requestId: number\n}\n\nexport const initialPairingPanelState: PairingPanelState = {\n target: null,\n busy: false,\n grant: null,\n link: null,\n qrDataURL: null,\n message: '',\n notice: '',\n requestId: 0,\n}\n\nexport type PairingPanelAction =\n /** \"Show QR code\" or switching address while the panel is open. */\n | { type: 'show'; target: PairingTarget; requestId: number }\n | { type: 'issued'; requestId: number; grant: PairingGrantSnapshot; link: string; qrDataURL: string }\n | { type: 'failed'; requestId: number; message: string }\n /** Clipboard result for the pairing string. */\n | { type: 'notice'; message: string }\n | { type: 'dismissNotice' }\n /** \"Hide QR code\": explicit close, or the single-use code expired. */\n | { type: 'close'; message?: string }\n\nexport function pairingPanelReduce(state: PairingPanelState, action: PairingPanelAction): PairingPanelState {\n switch (action.type) {\n case 'show':\n // Keep the panel open for the new target: the grant, the link and the QR\n // all belong to the previous address and are cleared until the new one\n // arrives, so a stale string can never be paired against a new host.\n return {\n target: action.target,\n busy: true,\n grant: null,\n link: null,\n qrDataURL: null,\n message: '',\n notice: '',\n requestId: action.requestId,\n }\n case 'issued':\n if (action.requestId !== state.requestId) return state\n return {\n ...state,\n busy: false,\n grant: action.grant,\n link: action.link,\n qrDataURL: action.qrDataURL,\n }\n case 'failed':\n if (action.requestId !== state.requestId) return state\n // The message stays on the now-empty panel so the user reads it where the\n // QR code was, instead of the panel silently collapsing.\n return { ...state, busy: false, grant: null, link: null, qrDataURL: null, message: action.message }\n case 'notice':\n return { ...state, notice: action.message }\n case 'dismissNotice':\n return state.notice === '' ? state : { ...state, notice: '' }\n case 'close':\n // Invalidate in-flight work so a late grant cannot reopen the panel.\n return { ...initialPairingPanelState, requestId: state.requestId + 1, message: action.message ?? '' }\n }\n}\n\nexport interface PairingPanelView {\n /** The panel (QR + pairing info, or its error state) is on screen. */\n open: boolean\n /** An issue is in flight; the toggle is disabled while it runs. */\n busy: boolean\n /** The last issue failed; the panel shows the message and a retry hint. */\n failed: boolean\n /** Button label key: show / generating / hide. */\n action: 'pair.qrShow' | 'pair.qrGenerating' | 'pair.qrHide'\n /** Address the visible payload pairs against; null while closed or loading. */\n target: PairingTarget | null\n link: string | null\n qrDataURL: string | null\n message: string\n notice: string\n}\n\nexport function pairingPanelView(state: PairingPanelState): PairingPanelView {\n // A target stays selected for as long as the panel is open, including the\n // failed state where there is a message to read but no payload yet.\n const open = state.target !== null\n return {\n open,\n busy: state.busy,\n failed: open && !state.busy && state.grant === null,\n action: state.busy ? 'pair.qrGenerating' : state.target === null ? 'pair.qrShow' : 'pair.qrHide',\n target: state.target,\n link: state.link,\n qrDataURL: state.qrDataURL,\n message: state.message,\n notice: state.notice,\n }\n}\n","export const DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE = 8\nexport const MAX_FUNNEL_CONNECTIONS_PER_SOURCE = 16\n\nexport function normalizeFunnelConnectionLimit(value: unknown): number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= MAX_FUNNEL_CONNECTIONS_PER_SOURCE\n ? value\n : DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE\n}\n","export const DEFAULT_LOCAL_PORT = 3098\nexport const MIN_LOCAL_PORT = 1024\nexport const MAX_LOCAL_PORT = 65_535\n\nexport function normalizeLocalPort(value: unknown): number {\n return typeof value === 'number'\n && Number.isInteger(value)\n && value >= MIN_LOCAL_PORT\n && value <= MAX_LOCAL_PORT\n ? value\n : DEFAULT_LOCAL_PORT\n}\n\n/** The LAN listener is TLS-only, so every advertised endpoint is `https://`. */\nexport function localEndpointURLs(addresses: readonly string[], port: number): string[] {\n const normalizedPort = normalizeLocalPort(port)\n return [...new Set(addresses)].map((address) => `https://${address}:${normalizedPort}`)\n}\n\nexport function localListenError(error: unknown, port: number): string {\n const code = (error as NodeJS.ErrnoException | undefined)?.code\n if (code === 'EADDRINUSE') return `local port ${port} is already in use`\n if (code === 'EACCES') return `permission denied while opening local port ${port}`\n return error instanceof Error ? error.message : String(error)\n}\n","/**\n * 设置页依赖的**接口**:一次声明页面消费的全部东西,外加一道归一化 seam。\n *\n * 迁移前页面签名是 `props: Record<string, any>`,20 个依赖全凭运行期 typeof\n * 守卫;拼错一个名字不会编译报错,只会在页面上变成一条诊断行。宿主注入面\n * (client/index.ts 的 inject 字面量)与页面之间没有任何类型级链接。\n *\n * 这里做两件事:\n * 1. `SettingsPageProps` 把 20 个依赖的类型钉住,宿主面与页面共享它;\n * 2. `normalizeSettingsPageProps` 是唯一的 seam:校验一次、缺省补齐、把\n * 「宿主没给全」折算成诊断列表与能力集合。页面体里不再出现任何 typeof。\n *\n * 关于 React 的硬约束:7 个 `useDeepPilot*` 是 hook,必须留在组件体内无条件\n * 调用,不能包进普通函数。因此 hook 缺失时在这里换成**模块级 fallback hook**\n * (引用恒定,React 不会把它当作 hook 顺序变化),缺省态与今天页面内的分支\n * 逐一对齐。\n */\n\nimport type {\n DebugState,\n EnabledState,\n LocalPortState,\n PageState,\n RemoteConnectionLimitState,\n RemoteEnabledState,\n} from './index.ts'\nimport type { DeepPilotReport, PairingGrantSnapshot, PushTestResult, RelayTestResult } from '../report-wire.ts'\nimport type { Translate } from './i18n.ts'\nimport { DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE } from '../funnel-policy.ts'\nimport { DEFAULT_LOCAL_PORT } from '../local-policy.ts'\n\n/** 一个选择器 hook:页面传恒等选择器取整份状态。 */\nexport type Selector<S> = (select: (state: S) => S) => S\n\nexport type ReportSelector = Selector<PageState>\nexport type EnabledSelector = Selector<EnabledState>\nexport type LocalPortSelector = Selector<LocalPortState>\nexport type RemoteEnabledSelector = Selector<RemoteEnabledState>\nexport type RemoteLimitSelector = Selector<RemoteConnectionLimitState>\nexport type DebugSelector = Selector<DebugState>\n\n/** 页面真正用到的报告字段(诊断与统计块都只读这些)。 */\nexport type SettingsReport = DeepPilotReport\n\nexport interface SettingsPageProps {\n // ---------- hooks(恒为函数:缺失时由 seam 换成 fallback) ----------\n useDeepPilotReport: ReportSelector\n useDeepPilotEnabled: EnabledSelector\n useDeepPilotLocalPort: LocalPortSelector\n useDeepPilotRemoteEnabled: RemoteEnabledSelector\n useDeepPilotRemoteConnectionLimit: RemoteLimitSelector\n useDeepPilotDebug: DebugSelector\n // ---------- 可选函数:在位情况见 `can` ----------\n refresh?: () => void\n beginPairing?: () => Promise<PairingGrantSnapshot>\n revokeDevice?: (deviceId: string) => Promise<unknown>\n setDeviceName?: (deviceId: string, customName: string | null) => Promise<unknown>\n testRelay?: () => Promise<RelayTestResult>\n testPush?: () => Promise<PushTestResult>\n setDeepPilotEnabled?: (enabled: boolean) => unknown\n setDeepPilotLocalPort?: (port: number) => Promise<unknown> | unknown\n setDeepPilotRemoteEnabled?: (enabled: boolean) => unknown\n setDeepPilotRemoteConnectionLimit?: (limit: number) => Promise<unknown> | unknown\n setDeepPilotDebug?: (enabled: boolean) => unknown\n /** 绑定的翻译函数;页面所有文案都经它。 */\n t: Translate\n}\n\n/** 可选能力的名字:页面的行为分支读集合,不再 typeof。 */\nexport type SettingsCapability =\n | 'refresh'\n | 'beginPairing'\n | 'revokeDevice'\n | 'setDeviceName'\n | 'testRelay'\n | 'testPush'\n | 'setEnabled'\n | 'setLocalPort'\n | 'setRemoteEnabled'\n | 'setRemoteLimit'\n | 'setDebug'\n\nexport interface SettingsPageSurface {\n props: SettingsPageProps\n can: ReadonlySet<SettingsCapability>\n /** 已翻译的诊断行,顺序与迁移前页面内的 diag[] 一致。 */\n diagnostics: string[]\n /** 报告 hook 整个缺失:统计/配对/系统区块整段跳过。 */\n reportHookMissing: boolean\n}\n\n// ---------- hook 缺失时的缺省态 ----------\n\nexport const MISSING_REPORT_HOOK: ReportSelector = () => ({ status: 'loading', report: null, message: '' })\nexport const MISSING_ENABLED_HOOK: EnabledSelector = () => ({ status: 'unavailable', enabled: true })\nexport const MISSING_LOCAL_PORT_HOOK: LocalPortSelector = () => ({ status: 'unavailable', value: DEFAULT_LOCAL_PORT })\nexport const MISSING_REMOTE_ENABLED_HOOK: RemoteEnabledSelector = () => ({ status: 'unavailable', enabled: false })\nexport const MISSING_REMOTE_LIMIT_HOOK: RemoteLimitSelector = () => ({ status: 'unavailable', value: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE })\nexport const MISSING_DEBUG_HOOK: DebugSelector = () => ({ status: 'unavailable', enabled: false })\n\n/** 诊断行的 key,集中在此便于对账(tests/settings-props.test.ts 逐条断言)。 */\nconst DIAG_KEY = {\n reportHook: 'diag.missingReportHook',\n enabledHook: 'diag.missingEnabledHook',\n localPortHook: 'diag.missingLocalPortHook',\n remoteEnabledHook: 'diag.missingRemoteEnabledHook',\n remoteLimitHook: 'diag.missingRemoteLimitHook',\n debugHook: 'diag.missingDebugHook',\n refresh: 'diag.missingRefresh',\n reveal: 'diag.missingReveal',\n rotate: 'diag.missingRotate',\n rename: 'diag.missingRename',\n testRelay: 'diag.missingTestRelay',\n testPush: 'diag.missingTestPush',\n setEnabled: 'diag.missingSetEnabled',\n setLocalPort: 'diag.missingSetLocalPort',\n setRemote: 'diag.missingSetRemote',\n setRemoteLimit: 'diag.missingSetRemoteLimit',\n setDebug: 'diag.missingSetDebug',\n settingsUnavailable: 'diag.settingsUnavailable',\n} as const\n\nconst CAPABILITY_BY_PROP: ReadonlyArray<[SettingsCapability, keyof SettingsPageProps]> = [\n ['refresh', 'refresh'],\n ['beginPairing', 'beginPairing'],\n ['revokeDevice', 'revokeDevice'],\n ['setDeviceName', 'setDeviceName'],\n ['testRelay', 'testRelay'],\n ['testPush', 'testPush'],\n ['setEnabled', 'setDeepPilotEnabled'],\n ['setLocalPort', 'setDeepPilotLocalPort'],\n ['setRemoteEnabled', 'setDeepPilotRemoteEnabled'],\n ['setRemoteLimit', 'setDeepPilotRemoteConnectionLimit'],\n ['setDebug', 'setDeepPilotDebug'],\n]\n\nconst isFn = (value: unknown): value is (...args: never[]) => unknown => typeof value === 'function'\n\n/**\n * 把宿主注入的原始对象归一化成页面可消费的面。\n *\n * 逐项复刻迁移前页面内的行为:hook 缺失换 fallback 并记诊断;函数缺失则该\n * 能力不进 `can` 并记诊断;诊断顺序与原先的 `diag[]` 完全一致(宿主过期时\n * 用户看到的技术诊断因此一字不差)。\n */\nexport function normalizeSettingsPageProps(raw: unknown): SettingsPageSurface {\n const source = (raw ?? {}) as Record<string, unknown>\n const t = typeof source.t === 'function' ? (source.t as Translate) : ((key: string) => key)\n const diagnostics: string[] = []\n const can = new Set<SettingsCapability>()\n\n const useReport = isFn(source.useDeepPilotReport) ? (source.useDeepPilotReport as ReportSelector) : MISSING_REPORT_HOOK\n const useEnabled = isFn(source.useDeepPilotEnabled) ? (source.useDeepPilotEnabled as EnabledSelector) : MISSING_ENABLED_HOOK\n const useLocalPort = isFn(source.useDeepPilotLocalPort) ? (source.useDeepPilotLocalPort as LocalPortSelector) : MISSING_LOCAL_PORT_HOOK\n const useRemoteEnabled = isFn(source.useDeepPilotRemoteEnabled) ? (source.useDeepPilotRemoteEnabled as RemoteEnabledSelector) : MISSING_REMOTE_ENABLED_HOOK\n const useRemoteLimit = isFn(source.useDeepPilotRemoteConnectionLimit) ? (source.useDeepPilotRemoteConnectionLimit as RemoteLimitSelector) : MISSING_REMOTE_LIMIT_HOOK\n const useDebug = isFn(source.useDeepPilotDebug) ? (source.useDeepPilotDebug as DebugSelector) : MISSING_DEBUG_HOOK\n\n // 顺序必须与迁移前页面内的 diag[] 一致,否则宿主过期时用户看到的技术诊断会变样。\n if (!isFn(source.useDeepPilotReport)) diagnostics.push(t(DIAG_KEY.reportHook))\n if (!isFn(source.useDeepPilotEnabled)) diagnostics.push(t(DIAG_KEY.enabledHook))\n if (!isFn(source.refresh)) diagnostics.push(t(DIAG_KEY.refresh))\n if (!isFn(source.beginPairing)) diagnostics.push(t(DIAG_KEY.reveal))\n if (!isFn(source.revokeDevice)) diagnostics.push(t(DIAG_KEY.rotate))\n if (!isFn(source.setDeviceName)) diagnostics.push(t(DIAG_KEY.rename))\n if (!isFn(source.testRelay)) diagnostics.push(t(DIAG_KEY.testRelay))\n if (!isFn(source.testPush)) diagnostics.push(t(DIAG_KEY.testPush))\n if (!isFn(source.setDeepPilotEnabled)) diagnostics.push(t(DIAG_KEY.setEnabled))\n if (!isFn(source.useDeepPilotLocalPort)) diagnostics.push(t(DIAG_KEY.localPortHook))\n if (!isFn(source.setDeepPilotLocalPort)) diagnostics.push(t(DIAG_KEY.setLocalPort))\n if (!isFn(source.useDeepPilotRemoteEnabled)) diagnostics.push(t(DIAG_KEY.remoteEnabledHook))\n if (!isFn(source.setDeepPilotRemoteEnabled)) diagnostics.push(t(DIAG_KEY.setRemote))\n if (!isFn(source.useDeepPilotRemoteConnectionLimit)) diagnostics.push(t(DIAG_KEY.remoteLimitHook))\n if (!isFn(source.setDeepPilotRemoteConnectionLimit)) diagnostics.push(t(DIAG_KEY.setRemoteLimit))\n if (!isFn(source.useDeepPilotDebug)) diagnostics.push(t(DIAG_KEY.debugHook))\n if (!isFn(source.setDeepPilotDebug)) diagnostics.push(t(DIAG_KEY.setDebug))\n\n for (const [capability, prop] of CAPABILITY_BY_PROP) {\n if (isFn(source[prop])) can.add(capability)\n }\n\n const props: SettingsPageProps = {\n useDeepPilotReport: useReport,\n useDeepPilotEnabled: useEnabled,\n useDeepPilotLocalPort: useLocalPort,\n useDeepPilotRemoteEnabled: useRemoteEnabled,\n useDeepPilotRemoteConnectionLimit: useRemoteLimit,\n useDeepPilotDebug: useDebug,\n t: t as Translate,\n refresh: isFn(source.refresh) ? (source.refresh as () => void) : undefined,\n beginPairing: isFn(source.beginPairing) ? (source.beginPairing as () => Promise<PairingGrantSnapshot>) : undefined,\n revokeDevice: isFn(source.revokeDevice) ? (source.revokeDevice as (deviceId: string) => Promise<unknown>) : undefined,\n setDeviceName: isFn(source.setDeviceName) ? (source.setDeviceName as SettingsPageProps['setDeviceName']) : undefined,\n testRelay: isFn(source.testRelay) ? (source.testRelay as () => Promise<RelayTestResult>) : undefined,\n testPush: isFn(source.testPush) ? (source.testPush as () => Promise<PushTestResult>) : undefined,\n setDeepPilotEnabled: isFn(source.setDeepPilotEnabled) ? (source.setDeepPilotEnabled as SettingsPageProps['setDeepPilotEnabled']) : undefined,\n setDeepPilotLocalPort: isFn(source.setDeepPilotLocalPort) ? (source.setDeepPilotLocalPort as SettingsPageProps['setDeepPilotLocalPort']) : undefined,\n setDeepPilotRemoteEnabled: isFn(source.setDeepPilotRemoteEnabled) ? (source.setDeepPilotRemoteEnabled as SettingsPageProps['setDeepPilotRemoteEnabled']) : undefined,\n setDeepPilotRemoteConnectionLimit: isFn(source.setDeepPilotRemoteConnectionLimit) ? (source.setDeepPilotRemoteConnectionLimit as SettingsPageProps['setDeepPilotRemoteConnectionLimit']) : undefined,\n setDeepPilotDebug: isFn(source.setDeepPilotDebug) ? (source.setDeepPilotDebug as SettingsPageProps['setDeepPilotDebug']) : undefined,\n }\n\n return { props, can, diagnostics, reportHookMissing: !isFn(source.useDeepPilotReport) }\n}\n","/**\n * 设置页的 view model:把原先住在渲染函数里的三块逻辑变成可单测的纯模块。\n *\n * 迁移前 `settings-page.ts` 是一个 1059 行的组件,funnel phase → {dot, label}、\n端口/连接数草稿的编辑与合法性、serviceStatus 派生全在渲染函数里,没有任何\n直接测试。这里按 pairing-panel.ts 的形状把它们拆成 state / action / reduce /\nview 四件套——shape 与该先例一致,但**不继承它唯一的泄漏**:view model 只返回\n语义值,i18n key 的映射留在页面(措辞归页面,测试不跟着措辞漂)。\n */\n\nimport type { DeepPilotReport } from '../report-wire.ts'\nimport { DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE, MAX_FUNNEL_CONNECTIONS_PER_SOURCE } from '../funnel-policy.ts'\nimport { DEFAULT_LOCAL_PORT, MAX_LOCAL_PORT, MIN_LOCAL_PORT } from '../local-policy.ts'\n\n// ---------- 传输 phase ----------\n\n/** 点位的视觉状态。空串 = 无点位。 */\nexport type Dot = '' | ' pbb-dotWarn' | ' pbb-dotOk' | ' pbb-dotBad'\n\n/** phase 的语义标签;页面负责把它映射成 i18n key。 */\nexport type RemotePhaseLabel =\n | 'disabled' | 'starting' | 'login_required' | 'online' | 'error' | 'unavailable' | 'stopped'\nexport type LocalPhaseLabel = 'disabled' | 'starting' | 'online' | 'error' | 'stopped'\n\nexport interface PhaseMeta<L extends string> {\n dot: Dot\n label: L\n}\n\nexport const REMOTE_PHASE_META: Record<DeepPilotReport['remote']['phase'], PhaseMeta<RemotePhaseLabel>> = {\n disabled: { dot: '', label: 'disabled' },\n starting: { dot: ' pbb-dotWarn', label: 'starting' },\n login_required: { dot: ' pbb-dotWarn', label: 'login_required' },\n online: { dot: ' pbb-dotOk', label: 'online' },\n error: { dot: ' pbb-dotBad', label: 'error' },\n unavailable: { dot: ' pbb-dotBad', label: 'unavailable' },\n stopped: { dot: '', label: 'stopped' },\n}\n\nexport const LOCAL_PHASE_META: Record<DeepPilotReport['local']['phase'], PhaseMeta<LocalPhaseLabel>> = {\n disabled: { dot: '', label: 'disabled' },\n starting: { dot: ' pbb-dotWarn', label: 'starting' },\n online: { dot: ' pbb-dotOk', label: 'online' },\n error: { dot: ' pbb-dotBad', label: 'error' },\n stopped: { dot: '', label: 'stopped' },\n}\n\n/** 从点位反推「需要注意 / 已在线」——原先页面用字符串 includes 猜类名。 */\nexport function dotState(dot: string | undefined): { attention: boolean; online: boolean } {\n return {\n attention: dot?.includes('pbb-dotBad') === true,\n online: dot?.includes('pbb-dotOk') === true,\n }\n}\n\n/** 服务状态:总开关未就绪 / 已关闭 / 需要注意 / 在线 / 仍在起。 */\nexport type ServiceStatusKind = 'loading' | 'off' | 'attention' | 'ready'\n\nexport interface ServiceStatus {\n kind: ServiceStatusKind\n dot: Dot\n}\n\nexport function serviceStatus(input: {\n enabled: boolean\n switchReady: boolean\n localDot: string | undefined\n remoteDot: string | undefined\n}): ServiceStatus {\n const local = dotState(input.localDot)\n const remote = dotState(input.remoteDot)\n const attention = local.attention || remote.attention\n const online = local.online || remote.online\n // 「两个传输都关闭」不是「仍在读取」:disabled / stopped 的 phase 本来\n // 就没有点位(dot 为空串),此前会落到 loading,页面永久显示「正在读取\n // 状态…」。没有点位且开关就绪时状态已经确定,按未启用展示。\n const hasSignal = (dot: string | undefined): boolean => dot !== undefined && dot !== ''\n const anySignal = hasSignal(input.localDot) || hasSignal(input.remoteDot)\n const kind: ServiceStatusKind = !input.switchReady\n ? 'loading'\n : !input.enabled\n ? 'off'\n : attention\n ? 'attention'\n : online\n ? 'ready'\n : anySignal\n ? 'loading'\n : 'off'\n const dot: Dot = !input.enabled || (!attention && !online && !anySignal)\n ? ''\n : attention\n ? ' pbb-dotBad'\n : online\n ? ' pbb-dotOk'\n : ' pbb-dotWarn'\n return { kind, dot }\n}\n\n// ---------- 数字草稿(本地端口 / Funnel 连接数) ----------\n\n/** 一个数字草稿的合法区间。 */\nexport interface NumericRange {\n min: number\n max: number\n fallback: number\n}\n\nexport const LOCAL_PORT_RANGE: NumericRange = { min: MIN_LOCAL_PORT, max: MAX_LOCAL_PORT, fallback: DEFAULT_LOCAL_PORT }\nexport const REMOTE_LIMIT_RANGE: NumericRange = {\n min: 1,\n max: MAX_FUNNEL_CONNECTIONS_PER_SOURCE,\n fallback: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE,\n}\n\nexport interface NumericDraftState {\n /** 输入框里的原文;空串表示尚未编辑。 */\n draft: string\n /** 上一次应用结果的消息;空串表示无消息。 */\n message: string\n /** 消息是否表示失败(页面据此染红)。 */\n failed: boolean\n}\n\nexport type NumericDraftAction =\n /** 输入框变化。 */\n | { type: 'edit'; draft: string }\n /** 外部值变化:把草稿同步回最新值。 */\n | { type: 'sync'; value: number }\n /** 应用完成:清空消息(也用于四秒后的自动清除)。 */\n | { type: 'applied' }\n /** 应用成功并给出提示文案。 */\n | { type: 'succeeded'; message: string }\n | { type: 'failed'; message: string }\n\nexport function initialNumericDraft(range: NumericRange): NumericDraftState {\n return { draft: String(range.fallback), message: '', failed: false }\n}\n\nexport function numericDraftReduce(state: NumericDraftState, action: NumericDraftAction, range: NumericRange): NumericDraftState {\n switch (action.type) {\n case 'edit':\n return { ...state, draft: action.draft }\n case 'sync':\n return { ...state, draft: String(action.value), message: '', failed: false }\n case 'applied':\n return { ...state, message: '', failed: false }\n case 'succeeded':\n return { ...state, message: action.message, failed: false }\n case 'failed':\n return { ...state, message: action.message, failed: true }\n }\n}\n\nexport interface NumericDraftView {\n /** 解析出的值;非法时为 NaN。 */\n value: number\n valid: boolean\n /** 与当前生效值相同(应用按钮据此禁用)。 */\n unchanged: boolean\n}\n\nexport function numericDraftView(state: NumericDraftState, current: number, range: NumericRange): NumericDraftView {\n const value = Number(state.draft)\n const valid = Number.isInteger(value) && value >= range.min && value <= range.max\n return { value, valid, unchanged: valid && value === current }\n}\n\n// ---------- 设备列表 ----------\n\n/** 页面渲染设备行所需的字段(report.devices 的子集)。 */\nexport interface SettingsDevice {\n deviceId: string\n deviceName: string\n customName?: string\n revokedAt?: number\n appVersion?: string\n fingerprint?: string\n lastSeenTs?: number\n}\n\n/** 已撤销的设备不展示。 */\nexport function visibleDevices(report: DeepPilotReport | null): SettingsDevice[] {\n return (report?.devices ?? []).filter((device) => device.revokedAt === undefined)\n}\n\n/** 设备展示名:自定义名优先,都没有则空串(兜底文案归页面)。 */\nexport function deviceLabel(device: { deviceName: string; customName?: string }): string {\n return (device.customName ?? device.deviceName).trim()\n}\n","import { createElement as h, useEffect, useId, useReducer, useRef, useState } from 'react'\nimport { Button, Switch } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { DeviceActions } from './device-actions.ts'\nimport { settingsIcon } from './settings-icons.ts'\nimport * as QRCode from 'qrcode/lib/browser.js'\nimport type { DeepPilotReport, PairingGrantSnapshot, PushTestResult, RelayTestResult, ReportDiagnosticFailure } from '../report-wire.ts'\nimport { encodePairingLink, selectPairingTargets, type PairingTarget } from '../pairing-qr.ts'\nimport { initialPairingPanelState, pairingPanelReduce, pairingPanelView } from './pairing-panel.ts'\nimport { translateWith as t } from './i18n.ts'\nimport {\n normalizeSettingsPageProps,\n type SettingsCapability,\n type SettingsPageProps,\n} from './settings-props.ts'\nimport type { PageState } from './index.ts'\nimport { DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE } from '../funnel-policy.ts'\nimport { DEFAULT_LOCAL_PORT } from '../local-policy.ts'\nimport {\n LOCAL_PHASE_META,\n LOCAL_PORT_RANGE,\n REMOTE_LIMIT_RANGE,\n REMOTE_PHASE_META,\n deviceLabel as deviceLabelOf,\n initialNumericDraft,\n numericDraftReduce,\n numericDraftView,\n serviceStatus,\n visibleDevices as visibleDevicesOf,\n type LocalPhaseLabel,\n type NumericDraftAction,\n type NumericDraftState,\n type RemotePhaseLabel,\n} from './settings-view-models.ts'\n\ntype T = (key: string, vars?: Readonly<Record<string, unknown>>) => string\n\n/** 中文结论由调用处提供,原始上游信息统一放入括号,保留排查依据。 */\nconst errorDetails = (error: unknown): string =>\n '(' + (error instanceof Error ? error.message : String(error)) + ')'\n\n/** 通道标题旁的短状态;完整端点和参数放入对应的连接选项。 */\nconst CHANNEL_STATE_KEY: Record<RemotePhaseLabel | LocalPhaseLabel, string> = {\n disabled: 'channel.state.disabled',\n starting: 'channel.state.starting',\n login_required: 'channel.state.login_required',\n online: 'channel.state.online',\n error: 'channel.state.error',\n unavailable: 'channel.state.unavailable',\n stopped: 'channel.state.stopped',\n}\n/** 服务状态 → i18n key。 */\nconst SERVICE_STATUS_KEY = {\n loading: 'status.loading',\n off: 'status.off',\n attention: 'status.attention',\n ready: 'status.ready',\n} as const\n\n/** Chevron icon (linear, currentColor). CSS rotates it 90° while its owner is\n * expanded, so collapsed always means \"points right, more content behind\". */\nconst ChevronIcon = (): any =>\n h('svg', {\n className: 'pbb-chevIcon',\n viewBox: '0 0 16 16',\n width: 12,\n height: 12,\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 1.5,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n 'aria-hidden': true,\n },\n h('path', { d: 'M6 3.5 10.5 8 6 12.5' }),\n )\n\n/** 诊断结果使用线性 SVG,与页面其余图标保持一致。 */\nconst CheckIcon = (): any =>\n h('svg', {\n viewBox: '0 0 16 16', width: 12, height: 12, fill: 'none', stroke: 'currentColor',\n strokeWidth: 1.6, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true,\n }, h('path', { d: 'M3.5 8.5 6.5 11.5 12.5 4.5' }))\n\nconst CrossIcon = (): any =>\n h('svg', {\n viewBox: '0 0 16 16', width: 12, height: 12, fill: 'none', stroke: 'currentColor',\n strokeWidth: 1.6, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true,\n }, h('path', { d: 'M4.5 4.5 11.5 11.5' }), h('path', { d: 'M11.5 4.5 4.5 11.5' }))\n\n/** One result line: SVG mark + text; the mark carries the pass/fail state. */\nconst resultRow = (ok: boolean, text: string, key: string): any =>\n h('p', { className: 'pbb-diag pbb-resultRow', key },\n h('span', { className: 'pbb-resultIcon' + (ok ? '' : ' pbb-resultIconBad') },\n ok ? CheckIcon() : CrossIcon()),\n h('span', null, text))\n\n/** 最近在线只细化到分钟:秒和年份对判断设备是否还连着没有意义。 */\nfunction formatLastSeen(ts: number | undefined): string {\n if (ts === undefined || !Number.isFinite(ts) || ts <= 0) return '—'\n return new Date(ts).toLocaleString(undefined, {\n month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit',\n })\n}\n\nasync function writeClipboard(t: T, value: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(value)\n return\n } catch {\n // Some embedded browsers expire user activation while a remote call is in\n // flight. Keep a synchronous fallback scoped to a short-lived textarea.\n }\n const textarea = document.createElement('textarea')\n textarea.value = value\n textarea.style.position = 'fixed'\n textarea.style.opacity = '0'\n document.body.appendChild(textarea)\n textarea.select()\n const copied = document.execCommand('copy')\n textarea.remove()\n if (!copied) throw new Error(t('clipboard.rejected'))\n}\n\n/**\n * Slot component: hooks come from the slot renderer, named use<Key>.\n *\n * 组件的接口是 `SettingsPageProps`(见 settings-props.ts):宿主注入面与页面\n * 共享同一份类型。这里只做一次归一化,之后全程消费类型化对象——页面里不再\n * 出现任何 typeof 守卫,也不再自己拼诊断行。\n */\nexport function DeepPilotSettingsPage(rawProps: Record<string, any>): any {\n const surface = normalizeSettingsPageProps(rawProps)\n const props: SettingsPageProps = surface.props\n const can = (capability: SettingsCapability): boolean => surface.can.has(capability)\n\n const [remoteLimitDraft, dispatchRemoteLimitDraft] = useReducer(\n (state: NumericDraftState, action: NumericDraftAction) => numericDraftReduce(state, action, REMOTE_LIMIT_RANGE),\n initialNumericDraft(REMOTE_LIMIT_RANGE),\n )\n const [localPortDraft, dispatchLocalPortDraft] = useReducer(\n (state: NumericDraftState, action: NumericDraftAction) => numericDraftReduce(state, action, LOCAL_PORT_RANGE),\n initialNumericDraft(LOCAL_PORT_RANGE),\n )\n const [selectedPairingHost, setSelectedPairingHost] = useState<string | null>(null)\n const [pairingOpen, setPairingOpen] = useState(false)\n const pageId = useId()\n const localOptionsId = pageId + '-local'\n const remoteOptionsId = pageId + '-remote'\n const troubleshootingId = pageId + '-troubleshooting'\n const systemId = pageId + '-system'\n const pairingId = pageId + '-pairing'\n const [pairingPanel, dispatchPairingPanel] = useReducer(pairingPanelReduce, initialPairingPanelState)\n const qrRequestId = useRef(0)\n const [troubleshootingOpen, setTroubleshootingOpen] = useState(false)\n const [relayTestBusy, setRelayTestBusy] = useState(false)\n const [relayTestResult, setRelayTestResult] = useState<RelayTestResult | null>(null)\n const [relayTestError, setRelayTestError] = useState('')\n const [pushTestBusy, setPushTestBusy] = useState(false)\n const [pushTestResult, setPushTestResult] = useState<PushTestResult | null>(null)\n const [pushTestError, setPushTestError] = useState('')\n const [deviceBusy, setDeviceBusy] = useState<string | null>(null)\n const [deviceMessage, setDeviceMessage] = useState('')\n const [editingDeviceId, setEditingDeviceId] = useState<string | null>(null)\n const [deviceNameDraft, setDeviceNameDraft] = useState('')\n /** 复制诊断信息的结果提示;failed 决定是否染红。 */\n const [diagnosticsCopy, setDiagnosticsCopy] = useState<{ message: string; failed: boolean }>({ message: '', failed: false })\n // 两条通道的「连接选项」都默认收起:端口、上限、帮助都是低频设置,不占首屏。\n const [localOptionsOpen, setLocalOptionsOpen] = useState(false)\n const [remoteOptionsOpen, setRemoteOptionsOpen] = useState(false)\n const [systemOpen, setSystemOpen] = useState(false)\n const [armedRevokeDeviceId, setArmedRevokeDeviceId] = useState<string | null>(null)\n const [nowMs, setNowMs] = useState(() => Date.now())\n\n useEffect(() => {\n if (!can('refresh')) return\n const refresh = props.refresh!\n refresh()\n const timer = globalThis.setInterval(() => refresh(), 3_000)\n return () => globalThis.clearInterval(timer)\n }, [props.refresh])\n\n const sendPushTest = (): void => {\n if (pushTestBusy) return\n if (!can('testPush')) {\n setPushTestError(t(props.t, 'push.staleHost'))\n return\n }\n setTroubleshootingOpen(true)\n setPushTestBusy(true)\n setPushTestError('')\n void props.testPush!().then((result: PushTestResult) => {\n setPushTestResult(result)\n setPushTestBusy(false)\n }, (error: unknown) => {\n setPushTestError(t(props.t, 'push.pushFailed') + errorDetails(error))\n setPushTestBusy(false)\n })\n }\n\n const runRelayTest = (): void => {\n if (relayTestBusy) return\n if (!can('testRelay')) {\n setRelayTestError(t(props.t, 'push.staleHostRelay'))\n return\n }\n setTroubleshootingOpen(true)\n setRelayTestBusy(true)\n setRelayTestError('')\n void props.testRelay!().then((result: RelayTestResult) => {\n setRelayTestResult(result)\n setRelayTestBusy(false)\n }, (error: unknown) => {\n setRelayTestError(t(props.t, 'push.relayBad') + errorDetails(error))\n setRelayTestBusy(false)\n })\n }\n\n // 两个草稿的「应用结果」消息四秒后自动消失。reducer 的 applied 动作把消息\n // 清空,因此这里只需要一个触发器。\n useEffect(() => {\n if (remoteLimitDraft.message === '') return\n const timer = globalThis.setTimeout(() => dispatchRemoteLimitDraft({ type: 'applied' }), 4_000)\n return () => globalThis.clearTimeout(timer)\n }, [remoteLimitDraft.message])\n\n useEffect(() => {\n if (localPortDraft.message === '') return\n const timer = globalThis.setTimeout(() => dispatchLocalPortDraft({ type: 'applied' }), 4_000)\n return () => globalThis.clearTimeout(timer)\n }, [localPortDraft.message])\n\n useEffect(() => {\n if (pairingPanel.grant === null) return\n // The panel carries a single-use code, so it must not outlive the grant.\n const remaining = Math.max(0, pairingPanel.grant.expiresAt - Date.now())\n const timer = globalThis.setTimeout(() => {\n dispatchPairingPanel({ type: 'close', message: t(props.t, 'pair.qrExpired') })\n }, remaining)\n return () => globalThis.clearTimeout(timer)\n }, [pairingPanel.grant])\n\n useEffect(() => {\n if (!pairingPanel.notice) return\n const timer = globalThis.setTimeout(() => dispatchPairingPanel({ type: 'dismissNotice' }), 2_500)\n return () => globalThis.clearTimeout(timer)\n }, [pairingPanel.notice])\n\n // hook 必须在组件体内无条件调用(React 规则):归一化 seam 已保证它们永远是\n // 函数——宿主没给时换成引用恒定的 fallback,缺省态与迁移前逐项对齐。\n // 它们仍是整个渲染里唯一可能抛的点(宿主 store 自己炸),因此保留渲染异常\n // 诊断:与迁移前一样折算成一行 diag.renderError 并把详情块展开。\n const diag = surface.diagnostics\n let failed = surface.reportHookMissing\n const readHooks = (): void => {\n const reportState = props.useDeepPilotReport((s: PageState) => s)\n hooks.report = reportState.report\n if (reportState.status === 'error' && reportState.message) {\n diag.push(t(props.t, 'diag.reportFailed') + errorDetails(reportState.message))\n failed = true\n }\n const enabledState = props.useDeepPilotEnabled((s) => s)\n hooks.enabled = enabledState.enabled\n hooks.switchReady = enabledState.status === 'ready'\n if (enabledState.status === 'unavailable') diag.push(t(props.t, 'diag.settingsUnavailable'))\n const localPortState = props.useDeepPilotLocalPort((s) => s)\n hooks.localPort = localPortState.value\n hooks.localPortReady = localPortState.status === 'ready'\n const remoteEnabledState = props.useDeepPilotRemoteEnabled((s) => s)\n hooks.remoteEnabled = remoteEnabledState.enabled\n hooks.remoteSwitchReady = remoteEnabledState.status === 'ready'\n const remoteLimitState = props.useDeepPilotRemoteConnectionLimit((s) => s)\n hooks.remoteConnectionLimit = remoteLimitState.value\n hooks.remoteConnectionLimitReady = remoteLimitState.status === 'ready'\n const debugState = props.useDeepPilotDebug((s) => s)\n hooks.debugEnabled = debugState.enabled\n hooks.debugSwitchReady = debugState.status === 'ready'\n }\n const hooks: {\n report: DeepPilotReport | null\n enabled: boolean\n switchReady: boolean\n localPort: number\n localPortReady: boolean\n remoteEnabled: boolean\n remoteSwitchReady: boolean\n remoteConnectionLimit: number\n remoteConnectionLimitReady: boolean\n debugEnabled: boolean\n debugSwitchReady: boolean\n } = {\n report: null, enabled: true, switchReady: false,\n localPort: DEFAULT_LOCAL_PORT, localPortReady: false,\n remoteEnabled: false, remoteSwitchReady: false,\n remoteConnectionLimit: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE, remoteConnectionLimitReady: false,\n debugEnabled: false, debugSwitchReady: false,\n }\n try {\n readHooks()\n } catch (error) {\n diag.push(t(props.t, 'diag.renderError') + errorDetails(error))\n failed = true\n }\n const report = hooks.report\n const enabled = hooks.enabled\n const switchReady = hooks.switchReady\n const localPort = hooks.localPort\n const localPortReady = hooks.localPortReady\n const remoteEnabled = hooks.remoteEnabled\n const remoteSwitchReady = hooks.remoteSwitchReady\n const remoteConnectionLimit = hooks.remoteConnectionLimit\n const remoteConnectionLimitReady = hooks.remoteConnectionLimitReady\n const debugEnabled = hooks.debugEnabled\n const debugSwitchReady = hooks.debugSwitchReady\n\n useEffect(() => {\n dispatchRemoteLimitDraft({ type: 'sync', value: remoteConnectionLimit })\n }, [remoteConnectionLimit])\n\n useEffect(() => {\n dispatchLocalPortDraft({ type: 'sync', value: localPort })\n }, [localPort])\n\n const localPortView = numericDraftView(localPortDraft, localPort, LOCAL_PORT_RANGE)\n const remoteLimitView = numericDraftView(remoteLimitDraft, remoteConnectionLimit, REMOTE_LIMIT_RANGE)\n const applyLocalPort = (): void => {\n if (!localPortView.valid || !can('setLocalPort')) {\n dispatchLocalPortDraft({ type: 'failed', message: t(props.t, 'local.portInvalid') })\n return\n }\n dispatchLocalPortDraft({ type: 'applied' })\n void Promise.resolve(props.setDeepPilotLocalPort!(localPortView.value)).then(() => {\n dispatchLocalPortDraft({ type: 'succeeded', message: t(props.t, 'local.portApplied') })\n }, (error: unknown) => {\n dispatchLocalPortDraft({\n type: 'failed',\n message: t(props.t, 'local.portFailed') + errorDetails(error),\n })\n })\n }\n\n const applyRemoteLimit = (): void => {\n if (!remoteLimitView.valid || !can('setRemoteLimit')) {\n dispatchRemoteLimitDraft({ type: 'failed', message: t(props.t, 'remote.limitInvalid') })\n return\n }\n dispatchRemoteLimitDraft({ type: 'applied' })\n void Promise.resolve(props.setDeepPilotRemoteConnectionLimit!(remoteLimitView.value)).then(() => {\n dispatchRemoteLimitDraft({ type: 'succeeded', message: t(props.t, 'remote.limitApplied') })\n }, (error: unknown) => {\n dispatchRemoteLimitDraft({\n type: 'failed',\n message: t(props.t, 'remote.limitFailed') + errorDetails(error),\n })\n })\n }\n\n const pairingTargets = report === null ? [] : selectPairingTargets(report.local, report.remote)\n const pairingTarget = pairingTargets.find(({ host }) => host === selectedPairingHost) ?? pairingTargets[0] ?? null\n const panel = pairingPanelView(pairingPanel)\n\n /**\n * Issue a grant and render the panel for one explicit target.\n *\n * The target is a parameter rather than component state on purpose: a click\n * handler must not depend on whether React has already re-rendered with the\n * newly selected host. A grant is bound to the host it was issued for, so\n * switching between LAN and public always mints a fresh one.\n */\n const showPairingQR = (target: PairingTarget): void => {\n if (!can('beginPairing')) return\n // Each request carries a token: a fast LAN/public switch can leave two\n // issues in flight, and only the newest may render its grant.\n const requestId = qrRequestId.current + 1\n qrRequestId.current = requestId\n dispatchPairingPanel({ type: 'show', target, requestId })\n void (props.beginPairing!() as Promise<PairingGrantSnapshot>)\n .then(async (grant: PairingGrantSnapshot) => {\n // The QR code and the copy field carry the same short link, so the app\n // accepts it from the camera and from the paste field alike.\n const link = encodePairingLink(target.host, grant, target.tlsFingerprint)\n return {\n grant,\n link,\n svg: await QRCode.toString(link, { type: 'svg', errorCorrectionLevel: 'M', margin: 2, width: 512 }),\n }\n })\n .then(({ grant, link, svg }) => {\n if (qrRequestId.current !== requestId) return\n dispatchPairingPanel({\n type: 'issued',\n requestId,\n grant,\n link,\n qrDataURL: 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg),\n })\n }, (error: unknown) => {\n if (qrRequestId.current !== requestId) return\n dispatchPairingPanel({\n type: 'failed',\n requestId,\n message: t(props.t, 'pair.qrFailed') + errorDetails(error),\n })\n })\n }\n\n const hidePairingQR = (): void => {\n // Invalidate any in-flight issue so a late response cannot reopen the panel.\n qrRequestId.current += 1\n dispatchPairingPanel({ type: 'close' })\n }\n\n const copyPairingInfo = (): void => {\n const link = pairingPanel.link\n if (link === null) return\n dispatchPairingPanel({ type: 'notice', message: '' })\n void writeClipboard(props.t as T, link).then(() => {\n dispatchPairingPanel({ type: 'notice', message: t(props.t, 'pair.infoCopyDone') })\n }, (error: unknown) => {\n dispatchPairingPanel({\n type: 'notice',\n message: t(props.t, 'pair.infoCopyFailed') + errorDetails(error),\n })\n })\n }\n\n // 运行信息只在系统信息展开后显示;TLS 指纹属于局域网连接选项。\n const advancedRows: any[] = []\n if (report !== null) {\n advancedRows.push(\n h('div', { className: 'pbb-runtimeRow', key: 'proto' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.protocolVersion')),\n h('span', { className: 'pbb-value' }, 'v' + String(report.protocolVersion)))),\n h('div', { className: 'pbb-runtimeRow', key: 'server' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.serverVersion')),\n h('span', { className: 'pbb-value' }, report.serverVersion))),\n h('div', { className: 'pbb-runtimeRow', key: 'path' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.identityPath')),\n h('span', { className: 'pbb-value' }, report.identityPath))),\n h('div', { className: 'pbb-runtimeRow', key: 'buffer' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.bufferMax')),\n h('span', { className: 'pbb-value' }, String(report.historyBufferMax) + t(props.t, 'advanced.frames')))),\n )\n }\n\n // Revocation is armed in-page first (delete, then confirm delete); it\n // used to be a window.confirm dialog. Disconnect semantics are\n // unchanged: the device is revoked immediately on confirmation.\n const revokeDevice = (deviceId: string, _name: string): void => {\n void _name\n if (!can('revokeDevice')) return\n setDeviceBusy(deviceId)\n setDeviceMessage('')\n void props.revokeDevice!(deviceId).then(() => {\n setDeviceMessage(t(props.t, 'devices.revoked'))\n }, (error: unknown) => {\n setDeviceMessage(t(props.t, 'devices.revokeFailed') + errorDetails(error))\n }).finally(() => {\n setDeviceBusy(null)\n })\n }\n\n const deviceLabel = (device: { deviceName: string; customName?: string }): string =>\n deviceLabelOf(device) || t(props.t, 'devices.unnamed')\n\n const beginDeviceRename = (device: { deviceId: string; deviceName: string; customName?: string }): void => {\n setArmedRevokeDeviceId(null)\n setEditingDeviceId(device.deviceId)\n setDeviceNameDraft(device.customName ?? device.deviceName)\n setDeviceMessage('')\n }\n\n const cancelDeviceRename = (): void => {\n setEditingDeviceId(null)\n setDeviceNameDraft('')\n setDeviceMessage('')\n }\n\n const saveDeviceName = (deviceId: string): void => {\n if (!can('setDeviceName')) return\n const normalized = deviceNameDraft.trim()\n if (normalized.length > 64) {\n setDeviceMessage(t(props.t, 'devices.nameInvalid'))\n return\n }\n setDeviceBusy(deviceId)\n setDeviceMessage('')\n void props.setDeviceName!(deviceId, normalized === '' ? null : normalized).then(() => {\n setDeviceMessage(normalized === '' ? t(props.t, 'devices.nameCleared') : t(props.t, 'devices.renamed'))\n setEditingDeviceId(null)\n setDeviceNameDraft('')\n }, (error: unknown) => {\n setDeviceMessage(t(props.t, 'devices.renameFailed') + errorDetails(error))\n }).finally(() => {\n setDeviceBusy(null)\n })\n }\n\n const visibleDevices = visibleDevicesOf(report)\n // 列表只保留名称、版本和最近在线;指纹与自定义标记移入更多操作。\n // 重命名表单和删除确认仍在设备行内展开,沿用原有保存与撤销语义。\n const deviceRows = visibleDevices.length > 0\n ? h('div', { className: 'pbb-deviceList' }, visibleDevices.map((d) => {\n const editing = editingDeviceId === d.deviceId\n const busy = deviceBusy === d.deviceId\n const label = deviceLabel(d)\n const fingerprint = d.fingerprint ?? ''\n const armed = armedRevokeDeviceId === d.deviceId\n return h('div', {\n className: 'pbb-deviceRow',\n key: d.deviceId,\n 'data-armed': armed || undefined,\n 'aria-busy': busy,\n 'aria-label': t(props.t, 'devices.col.name') + ': ' + label,\n },\n h('div', { className: 'pbb-deviceMain' },\n settingsIcon('phone'),\n h('div', { className: 'pbb-deviceText' },\n h('span', { className: 'pbb-deviceName', title: label }, label),\n h('div', { className: 'pbb-deviceMeta' },\n h('span', null, d.appVersion),\n h('span', null, t(props.t, 'devices.col.lastSeen') + ' ' + formatLastSeen(d.lastSeenTs))))),\n editing\n ? h('form', {\n className: 'pbb-deviceRenameForm',\n onSubmit: (event: { preventDefault: () => void }) => {\n event.preventDefault()\n saveDeviceName(d.deviceId)\n },\n },\n h('input', {\n className: 'pbb-deviceNameInput',\n type: 'text',\n value: deviceNameDraft,\n maxLength: 64,\n autoFocus: true,\n disabled: busy,\n placeholder: t(props.t, 'devices.namePlaceholder'),\n 'aria-label': t(props.t, 'devices.nameLabel'),\n onChange: (event: { currentTarget: { value: string } }) => setDeviceNameDraft(event.currentTarget.value),\n onKeyDown: (event: { key: string; preventDefault: () => void }) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n saveDeviceName(d.deviceId)\n } else if (event.key === 'Escape') {\n event.preventDefault()\n cancelDeviceRename()\n }\n },\n }),\n h('div', { className: 'pbb-deviceRenameActions' },\n h('button', {\n type: 'submit',\n className: 'pbb-action pbb-buttonPrimary',\n disabled: busy || deviceNameDraft.length > 64,\n title: busy ? t(props.t, 'devices.nameSaving') : t(props.t, 'devices.nameSave'),\n 'aria-label': busy ? t(props.t, 'devices.nameSaving') : t(props.t, 'devices.nameSave'),\n }, busy ? t(props.t, 'devices.nameSaving') : t(props.t, 'devices.nameSave')),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: busy,\n title: t(props.t, 'devices.nameCancel'),\n 'aria-label': t(props.t, 'devices.nameCancel'),\n onClick: cancelDeviceRename,\n }, t(props.t, 'devices.nameCancel'))),\n deviceNameDraft.length > 64\n ? h('p', { className: 'pbb-diag pbb-diagBad' }, t(props.t, 'devices.nameInvalid'))\n : null)\n : null,\n armed || editing ? null : h('div', { className: 'pbb-deviceActions' },\n busy\n ? h('span', { className: 'pbb-actionBusy', role: 'status' }, t(props.t, 'devices.deleting'))\n : h(DeviceActions, {\n name: label, fingerprint, customName: d.customName,\n canRename: editingDeviceId === null && can('setDeviceName'),\n canRevoke: can('revokeDevice'), t: props.t,\n onRename: () => beginDeviceRename(d),\n onRevoke: () => {\n cancelDeviceRename()\n setArmedRevokeDeviceId(d.deviceId)\n },\n })),\n armed && !busy\n ? h('div', { className: 'pbb-deviceConfirm' },\n h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, t(props.t, 'devices.revokeConfirm', { name: label })),\n h('div', { className: 'pbb-rowAction' },\n h('button', {\n type: 'button',\n className: 'pbb-action pbb-actionDangerGhost',\n 'aria-label': t(props.t, 'devices.revokeAria', { name: label }),\n onClick: () => {\n setArmedRevokeDeviceId(null)\n revokeDevice(d.deviceId, label)\n },\n }, t(props.t, 'devices.revoke')),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n onClick: () => setArmedRevokeDeviceId(null),\n }, t(props.t, 'devices.nameCancel'))))\n : null)\n }))\n : h('p', { className: 'pbb-empty' }, t(props.t, 'devices.empty'))\n\n const switchTitle = t(props.t, 'master.title')\n const localMeta = report === null ? null : LOCAL_PHASE_META[report.local.phase]\n const remoteMeta = report === null ? null : REMOTE_PHASE_META[report.remote.phase]\n // 服务状态与点位由 view model 推导:不再用类名 includes 反推布尔。\n const service = serviceStatus({\n enabled,\n switchReady: switchReady && report !== null,\n localDot: localMeta?.dot,\n remoteDot: remoteMeta?.dot,\n })\n const serviceStatusText = t(props.t, SERVICE_STATUS_KEY[service.kind])\n const localStateText = localMeta === null ? t(props.t, 'phase.unknown') : t(props.t, CHANNEL_STATE_KEY[localMeta.label])\n const remoteStateText = remoteMeta === null ? t(props.t, 'phase.unknown') : t(props.t, CHANNEL_STATE_KEY[remoteMeta.label])\n\n // ---------- 连接诊断(P0:最近失败可观测 + 一键复制) ----------\n\n /** 一条失败事件的单行文本:时间 · 类型 · 分因,附带可选排查字段。 */\n const diagnosticLine = (failure: ReportDiagnosticFailure): string => {\n const base = t(props.t, 'diagnostics.item', {\n time: new Date(failure.ts).toLocaleString(),\n kind: t(props.t, ({\n 'upgrade-rejected': 'diagnostics.kind.upgrade', 'pair-rejected': 'diagnostics.kind.pair',\n 'auth-failed': 'diagnostics.kind.auth', 'connection-opened': 'diagnostics.kind.opened',\n 'connection-closed': 'diagnostics.kind.closed', 'connection-error': 'diagnostics.kind.error',\n identity: 'diagnostics.kind.identity', storage: 'diagnostics.kind.storage',\n } as Record<string, string>)[failure.kind] ?? 'diagnostics.kind.unknown'),\n reason: '(' + failure.kind + ' / ' + failure.reason + ')',\n })\n const extras: string[] = []\n if (failure.attemptId !== undefined) extras.push(t(props.t, 'diagnostics.attempt', { id: failure.attemptId }))\n if (failure.closeCode !== undefined) extras.push(t(props.t, 'diagnostics.closeCode', { code: failure.closeCode }))\n if (failure.durationMs !== undefined) extras.push(t(props.t, 'diagnostics.duration', { ms: failure.durationMs }))\n if (failure.source !== undefined) extras.push(t(props.t, 'diagnostics.source', { label: failure.source }))\n return extras.length === 0 ? base : base + ' · ' + extras.join(' · ')\n }\n\n /**\n * 复制诊断信息:报告里的结构化事实(版本 / 相位 / 连接数 / 最近失败)。\n * 走既有的 report 通道与 i18n;内容不含配对码、公钥、APNs token 与消息正文。\n */\n const copyDiagnostics = (): void => {\n if (report === null) return\n const enabledText = report.enabled ? t(props.t, 'diagnostics.on') : t(props.t, 'diagnostics.off')\n const failures = report.diagnostics?.recentFailures ?? []\n const lines = [\n t(props.t, 'diagnostics.reportTitle'),\n t(props.t, 'diagnostics.reportGeneratedAt') + ': ' + new Date().toLocaleString(),\n t(props.t, 'diagnostics.reportVersion') + ': v' + report.pluginVersion\n + ' (' + t(props.t, 'advanced.protocolVersion') + ' v' + String(report.protocolVersion) + ')',\n t(props.t, 'diagnostics.reportEnabled') + ': ' + enabledText,\n t(props.t, 'diagnostics.reportLocal') + ': ' + report.local.phase\n + (report.local.phase === 'online' ? ' :' + String(report.local.port) : ''),\n t(props.t, 'diagnostics.reportRemote') + ': ' + report.remote.phase,\n t(props.t, 'diagnostics.reportConnections') + ': ' + String(report.activeConnections),\n ]\n if (report.diagnostics !== undefined) {\n lines.push(t(props.t, 'diagnostics.startedAt', {\n time: new Date(report.diagnostics.startedAt).toLocaleString(),\n }))\n }\n lines.push(t(props.t, 'diagnostics.reportFailureHeader') + ':')\n if (failures.length === 0) {\n lines.push('- ' + t(props.t, 'diagnostics.reportNone'))\n } else {\n for (const failure of failures.slice(-5).reverse()) lines.push('- ' + diagnosticLine(failure))\n }\n void writeClipboard(props.t, lines.join('\\n')).then(() => {\n setDiagnosticsCopy({ message: t(props.t, 'diagnostics.copied'), failed: false })\n }, (error: unknown) => {\n setDiagnosticsCopy({\n message: t(props.t, 'diagnostics.copyFailed') + errorDetails(error),\n failed: true,\n })\n })\n }\n\n // 诊断区块放在「测试与故障排查」卡片内:与推送自测同一处,用户排查时不必\n // 在两块之间来回找。report 为 null(报告未就绪)时整块跳过。\n const diagnosticsSection = report === null ? null : h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-row' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-testTitle' }, t(props.t, 'diagnostics.title')),\n h('span', { className: 'pbb-testDescription' }, t(props.t, 'diagnostics.description'))),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n onClick: copyDiagnostics,\n 'data-testid': 'diagnosticsCopy',\n }, t(props.t, 'diagnostics.copy'))),\n diagnosticsCopy.message\n ? h('p', { className: 'pbb-diag' + (diagnosticsCopy.failed ? ' pbb-diagBad' : ''), role: 'status' }, diagnosticsCopy.message)\n : null,\n report.diagnostics === undefined\n ? h('p', { className: 'pbb-diag' }, t(props.t, 'diagnostics.staleHost'))\n : (report.diagnostics.recentFailures.length === 0\n ? h('p', { className: 'pbb-diag' }, t(props.t, 'diagnostics.empty'))\n : h('div', null,\n h('span', { className: 'pbb-label' }, t(props.t, 'diagnostics.recent')),\n report.diagnostics.recentFailures.slice(-5).reverse().map((failure, index) =>\n h('p', { className: 'pbb-diag', key: String(index) }, diagnosticLine(failure))))),\n )\n\n // ---------- 新版布局的局部构造器(仅表现层) ----------\n\n // 原生 hidden 同时移出布局、焦点顺序和无障碍树;保留挂载以保留参数草稿。\n const fold = (open: boolean, body: any): any =>\n h('div', { className: 'pbb-fold', hidden: !open }, body)\n\n /** 配对倒计时:仅在 QR 面板打开且 grant 在场时每秒刷新一次。 */\n useEffect(() => {\n if (!panel.open || pairingPanel.grant === null) return\n const timer = globalThis.setInterval(() => setNowMs(Date.now()), 1_000)\n return () => globalThis.clearInterval(timer)\n }, [panel.open, pairingPanel.grant])\n\n // 剩余时间由 grant.expiresAt 精确算出;进度条按 5 分钟窗口(qrHint 文案所载)封顶换算,仅作展示。\n const grantRemainingMs = pairingPanel.grant === null\n ? 0\n : Math.max(0, pairingPanel.grant.expiresAt - nowMs)\n const grantRemainingText = String(Math.floor(grantRemainingMs / 60_000)) + ':'\n + String(Math.floor(grantRemainingMs / 1_000) % 60).padStart(2, '0')\n const grantRemainingPct = Math.min(100, (grantRemainingMs / 300_000) * 100)\n\n const recentFailures = report?.diagnostics?.recentFailures ?? []\n const troubleGood = relayTestResult !== null\n ? relayTestResult.overall === 'ok'\n : pushTestResult !== null\n ? pushTestResult.overall === 'sent'\n : false\n const troubleBad = relayTestResult !== null\n ? relayTestResult.overall !== 'ok'\n : pushTestResult !== null\n ? pushTestResult.overall !== 'sent'\n : recentFailures.length > 0\n const troubleConclusion = relayTestResult !== null\n ? (relayTestResult.overall === 'ok' ? t(props.t, 'push.relayOk') : t(props.t, 'push.relayBad'))\n : pushTestResult !== null\n ? (pushTestResult.overall === 'sent' ? t(props.t, 'push.pushSent') : t(props.t, 'push.pushFailed'))\n : recentFailures.length > 0\n ? t(props.t, 'diagnostics.historyCount', { count: recentFailures.length })\n : ''\n\n // 默认状态与已确认画布一致;配对面板只在用户点击添加后生成一次性凭据。\n const pairingSection = h('div', { id: pairingId, hidden: !pairingOpen },\n !pairingOpen || report === null ? null : h('div', { className: 'pbb-pairingPanel' },\n h('div', { className: 'pbb-pairingHeader' },\n h('h3', { className: 'pbb-cardTitle' }, t(props.t, 'pair.qrPanelTitle')),\n !panel.open && pairingTarget !== null\n ? h('button', {\n type: 'button', className: 'pbb-action',\n disabled: panel.busy || !report.pairingReady,\n onClick: () => showPairingQR(pairingTarget),\n }, t(props.t, 'pair.qrShow'))\n : null),\n h('div', { className: 'pbb-pairingBody' },\n pairingTarget === null\n ? h('p', { className: 'pbb-diag' }, enabled ? t(props.t, 'pair.noAddressHelp') : t(props.t, 'pair.disabledHelp'))\n : null,\n pairingTargets.length < 2 ? null : h('div', { className: 'pbb-targetList' },\n pairingTargets.map((target) => h('button', {\n type: 'button',\n key: target.host,\n className: 'pbb-targetButton' + (target.host === pairingTarget?.host ? ' pbb-targetSelected' : ''),\n // A grant is single-use and cannot be recalled, so a switch clicked\n // while one is already being issued would spend a second code that\n // nothing ever displays. Wait for the in-flight issue instead.\n disabled: panel.busy,\n onClick: () => {\n setSelectedPairingHost(target.host)\n // Switching between LAN and public keeps the panel open by\n // re-issuing a grant for the newly selected address, so both\n // networks are one tap away instead of a collapse and re-open.\n if (panel.open) showPairingQR(target)\n else hidePairingQR()\n },\n }, (target.kind === 'public' ? t(props.t, 'pair.kind.public') : t(props.t, 'pair.kind.lan')) + ' · ' + target.host)),\n ),\n panel.message ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, panel.message) : null,\n panel.notice ? h('p', { className: 'pbb-diag', role: 'status' }, panel.notice) : null,\n panel.failed && pairingTarget !== null\n ? h('div', { className: 'pbb-rowAction' },\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: panel.busy || (report !== null && !report.pairingReady),\n onClick: () => showPairingQR(pairingTarget),\n }, t(props.t, 'pair.qrRetry')))\n : null,\n panel.open && !panel.failed ? h('div', { className: 'pbb-qrPanel' },\n h('div', null,\n panel.qrDataURL === null ? h('p', { className: 'pbb-diag' }, t(props.t, 'pair.qrGenerating')) : h('img', {\n className: 'pbb-qrImage',\n src: panel.qrDataURL,\n alt: t(props.t, 'pair.qrAlt'),\n }),\n pairingPanel.grant === null ? null : h('div', { className: 'pbb-countdown' },\n h('div', { className: 'pbb-countdownBar' },\n h('i', { style: { transform: 'scaleX(' + String(grantRemainingPct / 100) + ')' } })),\n h('span', { className: 'pbb-countdownText' }, grantRemainingText)),\n ),\n h('div', { className: 'pbb-pairInfo' },\n // The only credentials row on this page: host, single-use code and\n // (for LAN) the certificate pin travel together in one string, so the\n // phone needs one paste and nothing is shown twice.\n panel.link === null ? null : h('div', { className: 'pbb-pairCodeBlock' },\n h('span', { className: 'pbb-pairCodeLabel' }, t(props.t, 'pair.infoLabel')),\n h('div', { className: 'pbb-pairCodeRow' },\n h('code', { className: 'pbb-pairCode' }, panel.link),\n h('button', {\n type: 'button',\n className: 'pbb-action pbb-buttonPrimary',\n onClick: copyPairingInfo,\n 'data-testid': 'pairingInfoCopy',\n }, t(props.t, 'panel.tokenAction.copy')))),\n h('p', { className: 'pbb-qrHint' },\n t(props.t, 'pair.qrHint', {\n kind: panel.target?.kind === 'public' ? t(props.t, 'pair.kind.public') : t(props.t, 'pair.kind.lan'),\n }),\n ),\n ),\n ) : null,\n ),\n ))\n\n return h('div', { className: 'pbb-section' },\n h('header', { className: 'pbb-pageHeader' },\n h('div', null,\n h('h2', { className: 'pbb-title' }, 'DeepPilot'),\n h('p', { className: 'pbb-intro' }, t(props.t, 'meta.intro'))),\n h('button', {\n type: 'button', className: 'pbb-refresh', disabled: !can('refresh'),\n onClick: () => props.refresh?.(),\n }, settingsIcon('refresh', 14), t(props.t, 'meta.refresh'))),\n h('section', { className: 'pbb-card pbb-connections', 'aria-label': t(props.t, 'connection.title') },\n h('div', { className: 'pbb-cardBody' },\n h('div', { className: 'pbb-masterRow' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-controlTitle' }, switchTitle),\n h('div', { className: 'pbb-serviceSummary' },\n h('span', { className: 'pbb-serviceState' + (service.kind === 'ready' ? ' pbb-ok' : service.kind === 'attention' ? ' pbb-bad' : '') },\n settingsIcon(service.kind === 'ready' ? 'ready' : service.kind === 'attention' ? 'attention' : 'info', 13)),\n h('span', null, serviceStatusText),\n h('span', { className: 'pbb-metaDivider', 'aria-hidden': true }),\n h('span', null, t(props.t, 'panel.activeConnections') + ' '\n + (report === null ? '—' : String(report.activeConnections))))),\n h(Switch, {\n checked: enabled,\n label: switchTitle,\n disabled: !switchReady,\n onChange: (next: boolean) => {\n if (can('setEnabled')) props.setDeepPilotEnabled!(next)\n },\n }),\n ),\n h('div', { className: 'pbb-channel' },\n h('div', { className: 'pbb-row pbb-channelRow' },\n settingsIcon('wifi'),\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-controlTitle' },\n t(props.t, 'local.title')),\n h('div', { className: 'pbb-channelState' }, h('span', { className: localMeta?.label === 'online' ? 'pbb-ok' : localMeta?.label === 'error' ? 'pbb-bad' : undefined }, localStateText))),\n h('button', {\n type: 'button', className: 'pbb-iconButton pbb-expand',\n 'aria-label': t(props.t, 'local.options'),\n 'aria-expanded': localOptionsOpen, 'aria-controls': localOptionsId,\n onClick: () => setLocalOptionsOpen(!localOptionsOpen),\n }, h('span', { className: 'pbb-chev' }, ChevronIcon())),\n ),\n report !== null && report.local.message && report.local.phase === 'error'\n ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, t(props.t, 'local.errorDetails', { message: report.local.message }))\n : null,\n report !== null && report.local.tlsIdentityRegenerated === true\n ? h('p', { className: 'pbb-diag pbb-diagBad' }, t(props.t, 'local.tlsRegenerated'))\n : null,\n fold(localOptionsOpen, h('div', { className: 'pbb-channelBody', id: localOptionsId },\n // 局域网连接常开:说明手机如何选路,替代原来的开关。\n h('p', { className: 'pbb-controlDescription' }, t(props.t, 'local.autoRoute')),\n report !== null && report.local.phase === 'online'\n ? h('p', { className: 'pbb-diag pbb-endpoint' }, report.local.endpoints.join(' · ')) : null,\n h('div', { className: 'pbb-limitRow' },\n h('div', { className: 'pbb-controlText' },\n h('label', { className: 'pbb-controlTitle', htmlFor: 'deeppilot-local-port' }, t(props.t, 'local.portTitle')),\n h('span', { className: 'pbb-controlDescription' }, t(props.t, 'local.portDescription')),\n !localPortView.valid\n ? h('p', { className: 'pbb-diag pbb-diagBad' }, t(props.t, 'local.portInvalid'))\n : localPortDraft.message\n ? h('p', {\n className: 'pbb-diag' + (localPortDraft.failed ? ' pbb-diagBad' : ''),\n }, localPortDraft.message)\n : null,\n ),\n h('div', { className: 'pbb-limitControl' },\n h('input', {\n id: 'deeppilot-local-port',\n className: 'pbb-numberInput',\n type: 'number',\n min: LOCAL_PORT_RANGE.min,\n max: LOCAL_PORT_RANGE.max,\n step: 1,\n inputMode: 'numeric',\n value: localPortDraft.draft,\n disabled: !localPortReady,\n 'aria-label': t(props.t, 'local.portTitle'),\n onChange: (event: { currentTarget: { value: string } }) => dispatchLocalPortDraft({ type: 'edit', draft: event.currentTarget.value }),\n onKeyDown: (event: { key: string; preventDefault: () => void }) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n applyLocalPort()\n }\n },\n }),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: !localPortReady || !localPortView.valid || localPortView.unchanged,\n onClick: applyLocalPort,\n }, t(props.t, 'remote.limitApply')),\n ),\n ),\n report !== null && report.local.phase === 'online' && report.local.tlsFingerprint\n ? h('div', { className: 'pbb-limitRow' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-controlTitle' }, t(props.t, 'local.tlsFingerprint')),\n h('code', { className: 'pbb-token' }, report.local.tlsFingerprint)))\n : null,\n )),\n ),\n h('div', { className: 'pbb-channel' },\n h('div', { className: 'pbb-row pbb-channelRow' },\n settingsIcon('globe'),\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-controlTitle' },\n t(props.t, 'remote.title')),\n h('div', { className: 'pbb-channelState' }, h('span', { className: remoteMeta?.label === 'online' ? 'pbb-ok' : (remoteMeta?.label === 'error' || remoteMeta?.label === 'unavailable') ? 'pbb-bad' : undefined }, remoteStateText), h('span', { className: 'pbb-metaDivider', 'aria-hidden': true }), h('span', null, 'Tailscale Funnel'))),\n h(Switch, {\n checked: remoteEnabled,\n label: t(props.t, 'remote.title'),\n disabled: !remoteSwitchReady,\n onChange: (next: boolean) => {\n if (can('setRemoteEnabled')) props.setDeepPilotRemoteEnabled!(next)\n },\n }),\n h('button', {\n type: 'button', className: 'pbb-iconButton pbb-expand',\n 'aria-label': t(props.t, 'remote.options'),\n 'aria-expanded': remoteOptionsOpen, 'aria-controls': remoteOptionsId,\n onClick: () => setRemoteOptionsOpen(!remoteOptionsOpen),\n }, h('span', { className: 'pbb-chev' }, ChevronIcon())),\n ),\n report !== null && report.remote.phase === 'login_required'\n && typeof report.remote.authURL === 'string' && report.remote.authURL.startsWith('https://')\n ? h('div', { className: 'pbb-rowAction' },\n h('a', { className: 'pbb-action pbb-buttonPrimary', href: report.remote.authURL, target: '_blank', rel: 'noreferrer' }, t(props.t, 'remote.openAuth')))\n : null,\n report !== null && report.remote.message && (report.remote.phase === 'error' || report.remote.phase === 'unavailable')\n ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, t(props.t, 'remote.errorDetails', { message: report.remote.message }))\n : null,\n fold(remoteOptionsOpen, h('div', { className: 'pbb-channelBody', id: remoteOptionsId },\n report !== null && report.remote.phase === 'online'\n ? h('p', { className: 'pbb-diag pbb-endpoint' }, report.remote.publicURL) : null,\n h('div', { className: 'pbb-limitRow' },\n h('div', { className: 'pbb-controlText' },\n h('label', { className: 'pbb-controlTitle', htmlFor: 'deeppilot-funnel-source-limit' }, t(props.t, 'remote.limitTitle')),\n h('span', { className: 'pbb-controlDescription' }, t(props.t, 'remote.limitDescription')),\n !remoteLimitView.valid\n ? h('p', { className: 'pbb-diag pbb-diagBad' }, t(props.t, 'remote.limitInvalid'))\n : remoteLimitDraft.message\n ? h('p', {\n className: 'pbb-diag' + (remoteLimitDraft.failed ? ' pbb-diagBad' : ''),\n }, remoteLimitDraft.message)\n : null,\n ),\n h('div', { className: 'pbb-limitControl' },\n h('input', {\n id: 'deeppilot-funnel-source-limit',\n className: 'pbb-numberInput',\n type: 'number',\n min: 1,\n max: REMOTE_LIMIT_RANGE.max,\n step: 1,\n inputMode: 'numeric',\n value: remoteLimitDraft.draft,\n disabled: !remoteConnectionLimitReady,\n 'aria-label': t(props.t, 'remote.limitTitle'),\n onChange: (event: { currentTarget: { value: string } }) => dispatchRemoteLimitDraft({ type: 'edit', draft: event.currentTarget.value }),\n onKeyDown: (event: { key: string; preventDefault: () => void }) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n applyRemoteLimit()\n }\n },\n }),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: !remoteConnectionLimitReady || !remoteLimitView.valid || remoteLimitView.unchanged,\n onClick: applyRemoteLimit,\n }, t(props.t, 'remote.limitApply')),\n ),\n ),\n h('details', { className: 'pbb-helpDisclosure' },\n h('summary', null, h('span', { className: 'pbb-chev' }, ChevronIcon()), t(props.t, 'help.remoteTitle')),\n h('div', { className: 'pbb-helpBody' },\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.recommended')),\n h('ol', { className: 'pbb-helpList' },\n h('li', null, t(props.t, 'help.step1')),\n h('li', null, t(props.t, 'help.step2')),\n h('li', null, t(props.t, 'help.step3')),\n h('li', null, t(props.t, 'help.step4')),\n ),\n h('p', { className: 'pbb-helpText' }, t(props.t, 'help.funnelHint')),\n ),\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.httpsTitle')),\n h('ol', { className: 'pbb-helpList' },\n h('li', null, t(props.t, 'help.httpsStep1')),\n h('li', null, t(props.t, 'help.httpsStep2')),\n h('li', null, t(props.t, 'help.httpsStep3')),\n ),\n h('p', { className: 'pbb-helpText' }, t(props.t, 'help.httpsHint')),\n ),\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.allowTitle')),\n h('p', { className: 'pbb-helpText' }, t(props.t, 'help.allowBody')),\n h('code', { className: 'pbb-helpCode' }, '\"nodeAttrs\": [\\n {\\n \"target\": [\"autogroup:member\"],\\n \"attr\": [\"funnel\"],\\n },\\n],'),\n h('p', { className: 'pbb-helpText' }, t(props.t, 'help.allowHint')),\n ),\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.faqTitle')),\n h('ul', { className: 'pbb-helpList' },\n h('li', null, t(props.t, 'help.faq1')),\n h('li', null, t(props.t, 'help.faq2')),\n h('li', null, t(props.t, 'help.faq3')),\n h('li', null, t(props.t, 'help.faq4')),\n ),\n ),\n h('div', { className: 'pbb-helpSection' },\n h('div', { className: 'pbb-helpHeading' }, t(props.t, 'help.securityTitle')),\n h('ul', { className: 'pbb-helpList' },\n h('li', null, t(props.t, 'help.security1')),\n h('li', null, t(props.t, 'help.security2')),\n h('li', null, t(props.t, 'help.security3')),\n h('li', null, t(props.t, 'help.security4')),\n h('li', null, t(props.t, 'help.security5')),\n ),\n h('p', { className: 'pbb-helpText' },\n t(props.t, 'help.docsPrefix'),\n h('a', { className: 'pbb-helpLink', href: 'https://tailscale.com/docs/features/tailscale-funnel', target: '_blank', rel: 'noreferrer' }, t(props.t, 'help.funnelDocs'))),\n ),\n )),\n )),\n ),\n ),\n ),\n h('section', { className: 'pbb-devicesSection', 'aria-label': t(props.t, 'devices.title') },\n h('div', { className: 'pbb-devicesHeader' },\n h('h3', { className: 'pbb-cardTitle' }, t(props.t, 'devices.title')),\n h('span', { className: 'pbb-deviceCount' }, t(props.t, 'devices.count', { count: visibleDevices.length })),\n h('div', { className: 'pbb-addAction' }, h(Button, {\n variant: 'outline', size: 'sm', icon: settingsIcon('plus', 16),\n disabled: panel.busy || report === null || !report.pairingReady || !can('beginPairing'),\n 'aria-expanded': pairingOpen, 'aria-controls': pairingId,\n onClick: () => {\n if (pairingOpen) { hidePairingQR(); setPairingOpen(false); return }\n setPairingOpen(true)\n if (pairingTarget !== null && report?.pairingReady) showPairingQR(pairingTarget)\n },\n }, t(props.t, pairingOpen ? 'pair.close' : 'pair.add')))),\n pairingSection,\n h('div', { className: 'pbb-card pbb-devicesCard' },\n deviceMessage ? h('p', {\n className: 'pbb-diag pbb-deviceMessage' + (deviceMessage.startsWith(t(props.t, 'devices.renameFailed')) || deviceMessage.startsWith(t(props.t, 'devices.revokeFailed')) ? ' pbb-diagBad' : ''),\n role: 'status',\n }, deviceMessage) : null,\n deviceRows)),\n h('section', { className: 'pbb-card pbb-tools', 'aria-label': t(props.t, 'tools.title') },\n h('div', { className: 'pbb-toolSection' },\n h('button', {\n type: 'button',\n className: 'pbb-cardHead',\n 'aria-expanded': troubleshootingOpen, 'aria-controls': troubleshootingId,\n onClick: () => setTroubleshootingOpen(!troubleshootingOpen),\n },\n settingsIcon('activity', 17),\n h('span', { className: 'pbb-cardTitle' }, t(props.t, 'troubleshooting.summary')),\n h('span', { className: 'pbb-toolMeta' + (troubleGood ? ' pbb-ok' : troubleBad && relayTestResult !== null ? ' pbb-bad' : '') }, troubleConclusion),\n h('span', { className: 'pbb-chev' }, ChevronIcon())),\n fold(troubleshootingOpen, h('div', { className: 'pbb-cardBody', id: troubleshootingId },\n h('div', { className: 'pbb-testGrid' },\n h('div', { className: 'pbb-testItem' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-testTitle' }, t(props.t, 'push.relayTitle')),\n h('span', { className: 'pbb-testDescription' }, t(props.t, 'push.relayDefault'))),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: relayTestBusy,\n onClick: runRelayTest,\n }, relayTestBusy ? t(props.t, 'push.relayTesting') : t(props.t, 'push.testRelay'))),\n h('div', { className: 'pbb-testItem' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-testTitle' }, t(props.t, 'push.testPush')),\n h('span', { className: 'pbb-testDescription' }, t(props.t, 'push.pushDefault'))),\n h('button', {\n type: 'button',\n className: 'pbb-action',\n disabled: pushTestBusy,\n onClick: sendPushTest,\n }, pushTestBusy ? t(props.t, 'push.pushSending') : t(props.t, 'push.testPush'))),\n h('div', { className: 'pbb-testItem' },\n h('div', { className: 'pbb-controlText' },\n h('span', { className: 'pbb-testTitle' }, t(props.t, 'troubleshooting.debugTitle')),\n h('span', { className: 'pbb-testDescription' }, t(props.t, 'troubleshooting.debugDescription'))),\n h(Switch, {\n checked: debugEnabled,\n label: t(props.t, 'troubleshooting.debugTitle'),\n disabled: !debugSwitchReady,\n onChange: (next: boolean) => {\n if (can('setDebug')) props.setDeepPilotDebug!(next)\n },\n }))),\n relayTestError ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, relayTestError) : null,\n relayTestResult === null\n ? null\n : h('div', { className: 'pbb-helpBody' },\n h('div', { className: 'pbb-row' },\n h('span', { className: 'pbb-label' }, relayTestResult.url || t(props.t, 'push.relayUrlEmpty')),\n h('code', { className: 'pbb-token ' + (relayTestResult.overall === 'ok' ? 'pbb-ok' : 'pbb-bad') },\n relayTestResult.overall === 'ok' ? t(props.t, 'push.relayOk') : t(props.t, 'push.relayBad')),\n ),\n relayTestResult.steps.map((step: any, index: number) =>\n resultRow(step.ok, (step.id === 'health' ? t(props.t, 'push.relayStep.health') : t(props.t, 'push.relayStep.enroll'))\n + (step.latencyMs !== undefined ? ` (${String(step.latencyMs)}ms)` : '')\n + '(' + step.message + ')', String(index))),\n ),\n pushTestError ? h('p', { className: 'pbb-diag pbb-diagBad', role: 'alert' }, pushTestError) : null,\n pushTestResult === null\n ? null\n : h('div', { className: 'pbb-helpBody' },\n h('div', { className: 'pbb-row' },\n h('code', { className: 'pbb-token ' + (pushTestResult.overall === 'sent' ? 'pbb-ok' : pushTestResult.overall === 'failed' ? 'pbb-bad' : '') },\n pushTestResult.overall === 'sent' ? t(props.t, 'push.pushSent')\n : pushTestResult.overall === 'failed' ? t(props.t, 'push.pushFailed')\n : pushTestResult.overall === 'no-targets' ? t(props.t, 'push.pushNoTargets') : t(props.t, 'push.pushNotEnabled'))),\n pushTestResult.message ? h('p', { className: 'pbb-diag' }, t(props.t, 'push.resultDetail', { message: pushTestResult.message })) : null,\n pushTestResult.results.map((r: any, index: number) =>\n resultRow(r.outcome === 'sent', r.name + '('\n + t(props.t, r.environment === 'production' ? 'push.environment.production' : r.environment === 'development' ? 'push.environment.development' : 'push.environment.other', { environment: r.environment }) + ') · '\n + t(props.t, r.outcome === 'sent' ? 'push.outcome.sent' : r.outcome === 'invalid-token' ? 'push.outcome.invalid' : r.outcome === 'failed' ? 'push.outcome.failed' : 'push.outcome.other', { outcome: r.outcome }) + (r.reason ? '(' + r.reason + ')' : '')\n + (r.tokenFingerprint ? ' token:' + r.tokenFingerprint + '…' : ''), String(index))),\n ),\n diagnosticsSection,\n )),\n ),\n report === null ? null : h('div', { className: 'pbb-toolSection' },\n h('button', {\n type: 'button',\n className: 'pbb-cardHead',\n 'aria-expanded': systemOpen, 'aria-controls': systemId,\n onClick: () => setSystemOpen(!systemOpen),\n },\n settingsIcon('info', 17),\n h('span', { className: 'pbb-cardTitle' }, t(props.t, 'system.summary')),\n h('span', { className: 'pbb-toolMeta' + (report.updateAvailable === true ? ' pbb-ok' : '') },\n 'v' + report.pluginVersion + (report.updateAvailable === true ? ' · ' + t(props.t, 'update.badge') : '')),\n h('span', { className: 'pbb-chev' }, ChevronIcon())),\n fold(systemOpen, h('div', { className: 'pbb-cardBody', id: systemId },\n h('div', { className: 'pbb-sectionIntro' },\n h('h3', { className: 'pbb-cardTitle' }, t(props.t, 'system.title'))),\n h('div', { className: 'pbb-runtimeList' },\n h('div', { className: 'pbb-runtimeRow' },\n h('span', { className: 'pbb-label' }, 'DeepPilot'),\n h('span', { className: 'pbb-value' }, 'v' + report.pluginVersion)),\n // 内嵌 helper 自报的 Tailscale 版本:远程连接从未启动(或 helper 缺失)\n // 时 Host 不带该字段,这里显示「未获取」而不是从 go.mod 猜一个值。\n h('div', { className: 'pbb-runtimeRow' },\n h('span', { className: 'pbb-label' }, t(props.t, 'advanced.tailscaleVersion')),\n h('span', { className: 'pbb-value' },\n report.remote.tailscaleVersion ?? t(props.t, 'advanced.tailscaleVersionUnknown'))),\n h('div', { className: 'pbb-runtimeRow' },\n h('span', { className: 'pbb-label' }, t(props.t, 'panel.identity')),\n h('span', { className: 'pbb-value' }, t(props.t, report.pairingReady ? 'panel.identityReady' : 'panel.identityNotReady'))),\n advancedRows,\n report.updateAvailable === true\n ? h('a', {\n className: 'pbb-updateRow',\n href: typeof report.releaseUrl === 'string' && /^https:\\/\\//.test(report.releaseUrl)\n ? report.releaseUrl\n : 'https://github.com/Mars-Sea/dsh-deeppilot/releases',\n target: '_blank',\n rel: 'noreferrer',\n },\n h('span', null, t(props.t, 'update.badge')),\n h('span', { className: 'pbb-chev' }, ChevronIcon()))\n : null))),\n )),\n diag.length > 0 ? h('details', {\n className: 'pbb-card pbb-disclosure pbb-diagnostics',\n open: failed,\n },\n // 与其它可折叠卡同一个 SVG 箭头:收起朝右,展开转 90° 朝下。\n h('summary', null,\n h('span', { className: 'pbb-chev' }, ChevronIcon()),\n h('span', { className: 'pbb-disclosureTitle' }, t(props.t, 'diag.summary'))),\n h('div', { className: 'pbb-disclosureBody' },\n h('p', { className: 'pbb-diag' + (failed ? ' pbb-diagBad' : '') },\n t(props.t, 'diag.prefix') + diag.join(' | ')))) : null,\n )\n}\n","/**\n * 设置页左侧导航里 DeepPilot 一行的图标。\n *\n * DSH 0.2.2 的设置壳为每个 `settings.section` 渲染\n * `renderSlot('settings.section.icon', { size, active }, { only: id, fallback })`:\n * 有同 id 的图标贡献就用它,否则画默认齿轮。壳负责按钮、文字和装饰性外框\n * (外框已 `aria-hidden`),图标只需按 `size` 画一个随文字颜色变化的线性 SVG。\n *\n * 不用 `icon.svg`:那是插件管理页的彩色品牌图(渐变填充、白底),放进导航行\n * 会和内置单色线性图标格格不入,也违反「图标统一用线性单色 SVG」的要求。\n * 这里画一部手机(DeepPilot 的职责是把手机接到这台电脑的 DSH),描边沿用\n * 设置页其他图标的 16×16 视图框和 1.5 线宽。\n */\nimport { createElement as h } from 'react'\n\n/** 壳传入的图标属性(`SettingsSectionIconOwnerProps`)。`active` 由壳的样式\n * 体现(文字颜色经 currentColor 传到描边),图标本身不需要分支。 */\nexport interface NavIconProps {\n size?: number\n active?: boolean\n}\n\n/** 导航行默认边长;壳当前固定传 16。 */\nconst DEFAULT_NAV_ICON_SIZE = 16\n\nexport const DeepPilotNavIcon = ({ size }: NavIconProps): any => {\n const edge = typeof size === 'number' && size > 0 ? size : DEFAULT_NAV_ICON_SIZE\n return h('svg', {\n viewBox: '0 0 16 16',\n width: edge,\n height: edge,\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 1.5,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n 'aria-hidden': true,\n focusable: 'false',\n },\n // 机身\n h('rect', { x: 4.25, y: 1.75, width: 7.5, height: 12.5, rx: 1.75 }),\n // 底部指示条\n h('path', { d: 'M7 11.75h2' }),\n )\n}\n","/**\n * Bind the rc.2 profile config form for the browser half of the plugin.\n * The adapter preserves the settings page's snapshot and rejected-write\n * behavior while the form reads and writes this plugin's profile entry.\n *\n * Structural types only (no value imports): the client bundle's runtime\n * require allowlist is react + @deepseek-ai/cordis.\n */\n\n/** Section fields the settings page reads; other config keys pass through. */\nexport interface SettingsSectionValue {\n enabled?: boolean\n local?: { enabled?: boolean; port?: number; [key: string]: unknown }\n remote?: { enabled?: boolean; maxConnectionsPerSource?: number; [key: string]: unknown }\n diagnostics?: { debug?: boolean; [key: string]: unknown }\n [key: string]: unknown\n}\n\nexport interface ScopeSnapshot {\n status: 'loading' | 'ready' | 'unavailable'\n value?: SettingsSectionValue\n writable?: boolean\n}\n\n/** The settings page's local snapshot and write contract. */\nexport interface SettingsScopeLike {\n getSnapshot(): ScopeSnapshot\n subscribe(listener: () => void): () => void\n set(field: string, value: unknown): Promise<void>\n unset(field: string): Promise<void>\n}\n\n/** 0.1.7 ConfigFormController surface used here (structural subset). */\ninterface ConfigFormLike {\n getSnapshot(): ScopeSnapshot\n subscribe(listener: () => void): () => void\n set(field: string, value: unknown): Promise<boolean>\n unset(field: string): Promise<boolean>\n}\n\n/** 0.1.7 `ctx.configForms` service face (structural subset). */\nexport interface ConfigFormsLike {\n get?(entryId: string): ConfigFormLike\n}\n\ninterface SettingsScopeProvider {\n /**\n * Cordis service lookup. Real contexts carry this and MUST be read through\n * it: a context proxy throws `cannot get property \"<name>\" without inject`\n * when an undeclared service property is read. The form is resolved through\n * `get` because it may be provided after this entry applies.\n */\n get(name: string): unknown\n}\n\n/**\n * Deep-unwrap live-update references in a snapshot section.\n *\n * Volatile fields can arrive as `{ get() }` references. The settings page\n * compares plain values, so unwrap them at this boundary.\n */\nfunction plainSection(value: SettingsSectionValue | undefined): SettingsSectionValue | undefined {\n if (value === null || typeof value !== 'object') return value\n if (typeof (value as { get?: unknown }).get === 'function') {\n return plainSection((value as { get: () => SettingsSectionValue }).get())\n }\n const plain: Record<string, unknown> = {}\n for (const [key, item] of Object.entries(value)) {\n plain[key] = item !== null && typeof item === 'object' ? plainSection(item as SettingsSectionValue) : item\n }\n return plain as SettingsSectionValue\n}\n\n/**\n * Adapt one config form to the settings page's local contract.\n *\n * The form resolves writes as `Promise<boolean>` (false = the Host rejected or\n * could not recover the write) where the scope face signals failure by\n * rejecting — the page's optimistic-write rollback only runs on rejection, so\n * a `false` must be translated into one.\n *\n * @param forms - the 0.1.7 configForms service, if the host provides it.\n * @param entryId - profile entry id.\n * @returns the adapted scope, or undefined when the service cannot resolve it.\n */\nexport function adaptConfigForm(forms: ConfigFormsLike | undefined, entryId: string): SettingsScopeLike | undefined {\n const form = forms?.get?.(entryId)\n if (form === undefined) return undefined\n const accept = async (pending: Promise<boolean>): Promise<void> => {\n if (!(await pending)) throw new Error('host rejected the settings write')\n }\n return {\n getSnapshot: () => {\n const snapshot = form.getSnapshot()\n return {\n status: snapshot.status,\n value: plainSection(snapshot.value),\n writable: snapshot.writable,\n }\n },\n subscribe: (listener) => form.subscribe(listener),\n set: (field, value) => accept(form.set(field, value)),\n unset: (field) => accept(form.unset(field)),\n }\n}\n\n/**\n * Bind the rc.2 form if its service is already provisioned. Callers that\n * apply first retry inside `ctx.inject(['configForms'], …)`.\n */\nexport function bindConfigForm(ctx: SettingsScopeProvider): SettingsScopeLike | undefined {\n return adaptConfigForm(ctx.get('configForms') as ConfigFormsLike | undefined, 'deeppilot')\n}\n","/**\n * Browser half of the dsh-deeppilot bundle.\n *\n * Registers a \"DeepPilot\" settings page following the exact structure of the\n * working settings pages in the harness: a controller + local snapshot store\n * surfaced to the slot component as a `use` hook, with\n * the report fetched Host-side through the deeppilot/report Typert Remote.\n * The master switch (enabled) is read/written through the shared settings\n * profile config form (`ctx.configForms.get('deeppilot')`), the same entry the\n * Host half reads.\n *\n * The slot `inject` MUST be a thunk returning the inject face — the renderer\n * calls `entry.inject(...)`; passing a plain object used to throw\n * \"inject is not a function\" inside the slot boundary and silently blank the\n * whole section. The component renders a visible diagnostic line on any\n * failure mode so a broken setup is never a silent blank panel.\n */\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { DeepPilotReport, PairingGrantSnapshot } from '../report-wire.ts'\nimport { createSnapshotStore } from './snapshot-store.ts'\nimport { mountReportRemote } from './report-mount.ts'\nimport type { ClientRemoteLike, ReportRemote } from './report-mount.ts'\nimport { registerLocale as registerDeepPilotLocale, t } from './i18n.ts'\nimport type { PushTestResult, RelayTestResult } from '../report-wire.ts'\nimport { injectCss } from './styles.ts'\nimport { DeepPilotSettingsPage } from './settings-page.ts'\nimport { DeepPilotNavIcon } from './nav-icon.ts'\nimport { DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE, normalizeFunnelConnectionLimit } from '../funnel-policy.ts'\nimport { DEFAULT_LOCAL_PORT, normalizeLocalPort } from '../local-policy.ts'\nimport {\n bindConfigForm,\n type ConfigFormsLike,\n type SettingsScopeLike,\n} from './config-form.ts'\n\nexport { DeepPilotSettingsPage } from './settings-page.ts'\n\ntype AnyCtx = Context & {\n locale?: {\n register: (key: string, table: unknown) => () => void\n bind: (key: string) => (k: string, vars?: Readonly<Record<string, unknown>>) => string\n getSnapshot?: () => { active: string; revision: number }\n }\n remote?: ClientRemoteLike\n slots?: {\n inject: (name: string, cb: () => unknown) => unknown\n register: (entry: unknown, component: unknown) => unknown\n }\n configForms?: ConfigFormsLike\n}\n\n/** Controller state surfaced to the page through the snapshot store. */\nexport interface PageState {\n status: 'loading' | 'ready' | 'error'\n report: DeepPilotReport | null\n /** Visible diagnostic message for the error state. */\n message: string\n}\n\n/** Master-switch state surfaced to the page through its own snapshot store. */\nexport interface EnabledState {\n status: 'loading' | 'ready' | 'unavailable'\n enabled: boolean\n}\n\nexport interface RemoteEnabledState {\n status: 'loading' | 'ready' | 'unavailable'\n enabled: boolean\n}\n\n/** Diagnostics toggle state (\"测试与故障排查\" panel), read from `diagnostics.debug`. */\nexport interface DebugState {\n status: 'loading' | 'ready' | 'unavailable'\n enabled: boolean\n}\n\nexport interface LocalPortState {\n status: 'loading' | 'ready' | 'unavailable'\n value: number\n}\n\nexport interface RemoteConnectionLimitState {\n status: 'loading' | 'ready' | 'unavailable'\n value: number\n}\n\n/** Bound translation function shape used everywhere in this file. The\n * t() helper from i18n.ts has the same signature; we name it T here so\n * consumers in the page can pass it through props without depending on\n * the i18n module directly. */\ntype T = (key: string, vars?: Readonly<Record<string, unknown>>) => string\n\n/** Polls the report remote and owns the page state transitions. */\nclass ReportController {\n private listeners = new Set<() => void>()\n private snap: PageState = { status: 'loading', report: null, message: '' }\n\n constructor(\n private readonly fetchReport: () => Promise<DeepPilotReport | null>,\n private readonly t: T,\n ) {}\n\n state(): PageState {\n return this.snap\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n dispose(): void {\n this.listeners.clear()\n }\n\n async refresh(): Promise<void> {\n try {\n const report = await this.fetchReport()\n this.snap = report !== null\n ? { status: 'ready', report, message: '' }\n : { status: 'error', report: null, message: this.t('diag.mountFailed') }\n } catch (error) {\n this.snap = { status: 'error', report: null, message: error instanceof Error ? error.message : String(error) }\n }\n this.emit()\n }\n\n private emit(): void {\n for (const listener of [...this.listeners]) {\n try { listener() } catch { /* listener errors stay isolated */ }\n }\n }\n}\n\n/**\n * Services this client entry cannot start without.\n *\n * `configForms` is provided by the settings-page fiber, which may activate\n * after this entry. It is attached through an optional injection below so\n * the entry can activate before the settings page does.\n */\nexport const inject: readonly string[] = ['slots', 'locale', 'remote']\n\nexport function apply(ctx: Context): void {\n if (typeof document !== 'undefined') injectCss()\n const anyCtx = ctx as AnyCtx\n\n // Hand the locale face our full zh/en dictionary. The page is reachable\n // without a locale face: t() falls back to a built-in copy of the same\n // table so missing host injection never blanks the UI.\n ctx.effect(\n () => registerDeepPilotLocale(ctx),\n 'dsh-deeppilot: locale dictionaries',\n )\n\n let namespace: ReportRemote | undefined\n let mountError: string | undefined\n\n const fetchReport = async (): Promise<DeepPilotReport | null> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n const result = await namespace.report()\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'diag.callFailed'))\n return result.value\n }\n\n const tPage: T = (key, vars) => t(ctx, key, vars)\n const controller = new ReportController(fetchReport, tPage)\n ctx.effect(() => () => controller.dispose(), 'dsh-deeppilot: report controller')\n const store = createSnapshotStore<PageState>(controller.state())\n controller.subscribe(() => store.set(controller.state()))\n\n ctx.effect(() => {\n let cancelled = false\n let unmount: (() => Promise<void>) | undefined\n if (anyCtx.remote === undefined) {\n mountError = t(ctx, 'diag.remoteUnavailable')\n void controller.refresh()\n return () => {}\n }\n void mountReportRemote(\n anyCtx.remote,\n () => ctx.get('remote.deeppilot') as ReportRemote | undefined,\n )\n .then((mounted) => {\n if (cancelled) { void mounted.dispose(); return }\n namespace = mounted.namespace\n unmount = mounted.dispose\n mountError = undefined\n void controller.refresh()\n }, (error: unknown) => {\n mountError = error instanceof Error ? error.message : String(error)\n void controller.refresh()\n })\n return () => {\n cancelled = true\n namespace = undefined\n if (unmount !== undefined) void unmount()\n }\n }, 'dsh-deeppilot: report remote mount')\n\n const beginPairing = async (): Promise<PairingGrantSnapshot> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n const result = await namespace.beginPairing()\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'pair.qrFailed'))\n return result.value\n }\n\n const revokeDevice = async (deviceId: string): Promise<void> => {\n if (namespace === undefined) throw new Error(t(ctx, 'diag.remoteUnmounted'))\n const result = await namespace.revokeDevice(deviceId)\n if (!result.ok || result.value !== true) throw new Error(result.ok ? t(ctx, 'devices.revokeFailed') : (result.error.message ?? t(ctx, 'devices.revokeFailed')))\n await controller.refresh()\n }\n\n const setDeviceName = async (deviceId: string, customName: string | null): Promise<string | null> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n if (typeof namespace.setDeviceName !== 'function') {\n throw new Error(t(ctx, 'devices.renameStaleHost'))\n }\n const result = await namespace.setDeviceName(deviceId, customName)\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'devices.renameFailed'))\n await controller.refresh()\n return result.value\n }\n\n const sendTestPush = async (): Promise<PushTestResult> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n if (typeof namespace.testPush !== 'function') {\n throw new Error(t(ctx, 'push.staleHostPush'))\n }\n const result = await namespace.testPush()\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'push.pushFailed'))\n return result.value\n }\n\n const testRelayConnection = async (): Promise<RelayTestResult> => {\n if (namespace === undefined) {\n throw new Error(mountError !== undefined\n ? t(ctx, 'diag.mountFailedShort') + mountError\n : t(ctx, 'diag.remoteUnmounted'))\n }\n if (typeof namespace.testRelay !== 'function') {\n throw new Error(t(ctx, 'push.staleHostPushRelay'))\n }\n const result = await namespace.testRelay()\n if (!result.ok) throw new Error(result.error.message ?? t(ctx, 'push.relayBad'))\n return result.value\n }\n\n // Master switch: mirror the durable `enabled` field of the deeppilot\n // profile config entry shared with the Host half.\n const enabledStore = createSnapshotStore<EnabledState>({ status: 'loading', enabled: true })\n let scope: SettingsScopeLike | undefined = bindConfigForm(anyCtx)\n /** Adopters registered before attachScope runs, so a late-bound config form\n * still subscribes all. */\n const scopeAdoptions: Array<() => void> = []\n const adoptEnabled = (): void => {\n if (scope === undefined) return\n const snap = scope.getSnapshot()\n if (snap.status === 'ready' && snap.value !== undefined) {\n enabledStore.set({ status: 'ready', enabled: snap.value.enabled !== false })\n } else if (snap.status === 'unavailable') {\n enabledStore.set({ status: 'unavailable', enabled: true })\n }\n }\n scopeAdoptions.push(adoptEnabled)\n\n // Track the last scope-confirmed value so a rejected write can roll the\n // optimistic store back instead of leaving the UI in a state the Host never\n // accepted. Seed from adoptEnabled's result by reading the store.\n const lastConfirmedEnabled = (): boolean => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready' && snap.value !== undefined) return snap.value.enabled !== false\n // Pre-adopt fallback so the first flip still has a sane rollback target.\n return enabledStore.getSnapshot().enabled\n }\n const localPortStore = createSnapshotStore<LocalPortState>({ status: 'loading', value: DEFAULT_LOCAL_PORT })\n const lastConfirmedLocalPort = (): number => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready') return normalizeLocalPort(snap.value?.local?.port)\n return localPortStore.getSnapshot().value\n }\n const lastConfirmedRemoteEnabled = (): boolean => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready') return snap.value?.remote?.enabled === true\n return remoteEnabledStore.getSnapshot().enabled\n }\n const lastConfirmedRemoteConnectionLimit = (): number => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready') return normalizeFunnelConnectionLimit(snap.value?.remote?.maxConnectionsPerSource)\n return remoteConnectionLimitStore.getSnapshot().value\n }\n\n const setDeepPilotEnabled = (value: boolean): void => {\n const previous = lastConfirmedEnabled()\n enabledStore.set({ status: 'ready', enabled: value })\n if (scope === undefined) return\n void scope.set('enabled', value).then(() => { /* next adoptEnabled will refresh */ }, (error: unknown) => {\n // Roll the store back so the switch reflects the durable truth, and\n // surface the failure: silent rejections used to leave a \"turned off\"\n // UI live with a still-on Host until the next unrelated change.\n enabledStore.set({ status: 'ready', enabled: previous })\n const message = error instanceof Error ? error.message : String(error)\n console.error('[deeppilot] failed to persist enabled=' + String(value) + ': ' + message)\n })\n }\n\n const adoptLocal = (): void => {\n if (scope === undefined) return\n const snap = scope.getSnapshot()\n if (snap.status === 'ready') {\n localPortStore.set({ status: 'ready', value: normalizeLocalPort(snap.value?.local?.port) })\n } else if (snap.status === 'unavailable') {\n localPortStore.set({ status: 'unavailable', value: DEFAULT_LOCAL_PORT })\n }\n }\n scopeAdoptions.push(adoptLocal)\n\n const setDeepPilotLocalPort = async (value: number): Promise<void> => {\n const next = normalizeLocalPort(value)\n if (next !== value) throw new RangeError('local port must be an integer between 1024 and 65535')\n if (scope === undefined) throw new Error('settings scope unavailable')\n const previous = lastConfirmedLocalPort()\n localPortStore.set({ status: 'ready', value: next })\n const currentLocal = scope.getSnapshot().value?.local ?? {}\n try {\n await scope.set('local', { ...currentLocal, port: next })\n } catch (error) {\n localPortStore.set({ status: 'ready', value: previous })\n console.error('[deeppilot] failed to persist local.port=' + String(next) + ': ' + (error instanceof Error ? error.message : String(error)))\n throw error\n }\n }\n\n // Diagnostics toggle: defaults false, unlike enabled/local which default true.\n const debugStore = createSnapshotStore<DebugState>({ status: 'loading', enabled: false })\n const adoptDebug = (): void => {\n if (scope === undefined) return\n const snap = scope.getSnapshot()\n if (snap.status === 'ready') {\n debugStore.set({ status: 'ready', enabled: snap.value?.diagnostics?.debug === true })\n } else if (snap.status === 'unavailable') {\n debugStore.set({ status: 'unavailable', enabled: false })\n }\n }\n scopeAdoptions.push(adoptDebug)\n const lastConfirmedDebug = (): boolean => {\n const snap = scope?.getSnapshot()\n if (snap?.status === 'ready') return snap.value?.diagnostics?.debug === true\n return debugStore.getSnapshot().enabled\n }\n const setDeepPilotDebug = (value: boolean): void => {\n const previous = lastConfirmedDebug()\n debugStore.set({ status: 'ready', enabled: value })\n if (scope === undefined) return\n const currentDiagnostics = scope.getSnapshot().value?.diagnostics ?? {}\n void scope.set('diagnostics', { ...currentDiagnostics, debug: value }).then(() => {}, (error: unknown) => {\n debugStore.set({ status: 'ready', enabled: previous })\n console.error('[deeppilot] failed to persist diagnostics.debug=' + String(value) + ': ' + (error instanceof Error ? error.message : String(error)))\n })\n }\n\n const remoteEnabledStore = createSnapshotStore<RemoteEnabledState>({ status: 'loading', enabled: false })\n const remoteConnectionLimitStore = createSnapshotStore<RemoteConnectionLimitState>({\n status: 'loading',\n value: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE,\n })\n const adoptRemoteEnabled = (): void => {\n if (scope === undefined) return\n const snap = scope.getSnapshot()\n if (snap.status === 'ready') {\n remoteEnabledStore.set({ status: 'ready', enabled: snap.value?.remote?.enabled === true })\n remoteConnectionLimitStore.set({\n status: 'ready',\n value: normalizeFunnelConnectionLimit(snap.value?.remote?.maxConnectionsPerSource),\n })\n } else if (snap.status === 'unavailable') {\n remoteEnabledStore.set({ status: 'unavailable', enabled: false })\n remoteConnectionLimitStore.set({ status: 'unavailable', value: DEFAULT_FUNNEL_CONNECTIONS_PER_SOURCE })\n }\n }\n scopeAdoptions.push(adoptRemoteEnabled)\n\n // Attach once every adopter is registered. The form is an optional\n // injection because the settings-page fiber may provide it later.\n const attachScope = (): void => {\n if (scope === undefined) return\n for (const adopt of scopeAdoptions) {\n scope.subscribe(adopt)\n adopt()\n }\n }\n attachScope()\n if (scope === undefined) {\n const bindScopeFrom = (sub: AnyCtx): void => {\n if (scope !== undefined) return\n scope = bindConfigForm(sub)\n attachScope()\n }\n ctx.inject(['configForms'], (sub) => { bindScopeFrom(sub as AnyCtx) })\n }\n\n const setDeepPilotRemoteEnabled = (value: boolean): void => {\n const previous = lastConfirmedRemoteEnabled()\n remoteEnabledStore.set({ status: 'ready', enabled: value })\n if (scope === undefined) return\n const currentRemote = scope.getSnapshot().value?.remote ?? {}\n void scope.set('remote', { ...currentRemote, enabled: value }).then(() => { /* next adopt refreshes */ }, (error: unknown) => {\n remoteEnabledStore.set({ status: 'ready', enabled: previous })\n const message = error instanceof Error ? error.message : String(error)\n console.error('[deeppilot] failed to persist remote.enabled=' + String(value) + ': ' + message)\n })\n }\n\n const setDeepPilotRemoteConnectionLimit = async (value: number): Promise<void> => {\n const next = normalizeFunnelConnectionLimit(value)\n if (next !== value) throw new RangeError('maxConnectionsPerSource must be an integer between 1 and 16')\n if (scope === undefined) throw new Error('settings scope unavailable')\n const previous = lastConfirmedRemoteConnectionLimit()\n remoteConnectionLimitStore.set({ status: 'ready', value: next })\n const currentRemote = scope.getSnapshot().value?.remote ?? {}\n try {\n await scope.set('remote', { ...currentRemote, maxConnectionsPerSource: next })\n } catch (error) {\n remoteConnectionLimitStore.set({ status: 'ready', value: previous })\n const message = error instanceof Error ? error.message : String(error)\n console.error('[deeppilot] failed to persist remote.maxConnectionsPerSource=' + String(next) + ': ' + message)\n throw error\n }\n }\n\n if (anyCtx.slots === undefined) {\n // locale/configForms/remote all have visible degradations when missing;\n // slots is the registration seam itself — a missing slot service means\n // the whole page is silently blank. Surface it loudly so the cause shows\n // up next to the other diagnostic lines.\n console.error('[deeppilot] settings slots service unavailable; the DeepPilot section will not appear')\n }\n anyCtx.slots?.inject('settings.section', () =>\n (anyCtx.slots as NonNullable<AnyCtx['slots']>).register({\n name: 'settings.section',\n id: 'deeppilot',\n order: 13,\n label: () => {\n const bind = anyCtx.locale?.bind('settings.deeppilot')\n return bind ? bind('nav') : 'DeepPilot'\n },\n locale: 'settings.deeppilot',\n inject: () => ({\n hooks: {\n deepPilotReport: store,\n deepPilotEnabled: enabledStore,\n deepPilotLocalPort: localPortStore,\n deepPilotRemoteEnabled: remoteEnabledStore,\n deepPilotRemoteConnectionLimit: remoteConnectionLimitStore,\n deepPilotDebug: debugStore,\n },\n refresh: () => { void controller.refresh() },\n beginPairing,\n revokeDevice,\n setDeviceName,\n testRelay: testRelayConnection,\n testPush: sendTestPush,\n setDeepPilotEnabled,\n setDeepPilotLocalPort,\n setDeepPilotRemoteEnabled,\n setDeepPilotRemoteConnectionLimit,\n setDeepPilotDebug,\n // Bound translation function for the page. The page never imports\n // t() directly so it can be re-supplied if the host swaps the\n // locale face at runtime (a feature today; exercised in tests).\n t: (key: string, vars?: Readonly<Record<string, unknown>>) => t(ctx, key, vars),\n }),\n }, DeepPilotSettingsPage),\n )\n // 导航图标:DSH 0.2.2 起设置壳声明 `settings.section.icon`,按与上面\n // `settings.section` 相同的 id 匹配。`inject` 跟随插槽声明的生命周期,\n // 旧宿主的壳不声明这个插槽,回调不会触发,导航行保留默认图标。\n // 壳不显示 `label`,图标自身也 aria-hidden,可读名称仍来自上面的 label。\n anyCtx.slots?.inject('settings.section.icon', () =>\n (anyCtx.slots as NonNullable<AnyCtx['slots']>).register({\n name: 'settings.section.icon',\n id: 'deeppilot',\n }, DeepPilotNavIcon),\n )\n}\n"],"ignoreList":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"mappings":"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"}