/** * English dictionary — visionA Cloud * * Must contain the exact same set of keys as zh-Hant.ts (the unit test enforces this). */ import type { Dictionary } from "../types"; export const en: Dictionary = { // ── App ── "app.title": "visionA Cloud", "app.tagline": "Extending the local-tool experience to the cloud", // ── Common ── "common.loading": "Loading…", "common.error": "Something went wrong", "common.cancel": "Cancel", "common.confirm": "Confirm", "common.save": "Save", "common.close": "Close", "common.retry": "Retry", "common.view": "View", "common.manage": "Manage", "common.connect": "Connect", "common.disconnect": "Disconnect", "common.delete": "Delete", "common.edit": "Edit", "common.back": "Back", "common.na": "—", // ── Sidebar navigation ── "nav.dashboard": "Dashboard", "nav.devices": "Devices", "nav.models": "Models", "nav.conversion": "Convert", "nav.workspace": "Workspace", "nav.clusters": "Clusters", "nav.settings": "Settings", // ── Prototype banner ── // Phase 0.7 stage deployment fix: OIDC is wired to Innovedus Account Center; remove "no real auth" wording. "banner.prototype": "🚧 Prototype build · Member Center login enabled, but some flows are UI mockups; sample data only.", "banner.prototype.short": "🚧 Prototype (demo)", "banner.prototype.ariaLabel": "Prototype notice", // ── Header ── "header.toggleTheme": "Toggle theme", "header.toggleLocale": "Toggle language", "header.userMenu.open": "Open user menu", "header.userMenu.profile": "Account settings", "header.userMenu.logout": "Sign out", "header.userMenu.fallbackName": "User", "header.breadcrumb.home": "Home", // ── Tunnel / remote status ── "tunnel.status.online": "Connected", "tunnel.status.offline": "Offline", "tunnel.status.reconnecting": "Reconnecting", "tunnel.rttLabel": "RTT {rtt}ms", // ── Theme toggle ── "theme.light": "Light", "theme.dark": "Dark", "theme.system": "System", // ── Auth (Phase 0.6 OIDC redirect mode) ── // Design notes: // - All email/password form keys removed; visionA delegates auth to Innovedus Member Center // - Shared sign-in/out copy lives under `auth.action.*` so non-form callsites (e.g. header // dropdown) no longer borrow `auth.login.submit` "auth.action.signIn": "Sign in", "auth.action.signOut": "Sign out", // Login page "auth.login.title": "Sign in to visionA Cloud", "auth.login.subtitle": "Welcome back to visionA Cloud", "auth.login.welcomeBack": "Welcome back", "auth.login.signInWithMC": "Sign in with your Innovedus account", "auth.login.button": "Sign in", "auth.login.noAccount": "Don't have an account?", "auth.login.registerLink": "Register now", "auth.login.prototypeHint": "Phase 0.6 prototype — sign-in redirects to the Innovedus Account Center for verification.", // Register page (Phase 0.6: visionA no longer hosts a sign-up form; redirects to Member Center) "auth.register.title": "Register for visionA", "auth.register.description": "visionA uses the Innovedus unified account system.", "auth.register.howTo": "Please register at the Innovedus Account Center. Once done you can sign in to visionA.", "auth.register.button": "Go to Innovedus Account Center", "auth.register.disabledHint": "Innovedus Account Center URL is not configured. Please contact the administrator.", "auth.register.alreadyHaveAccount": "Already have an account?", "auth.register.loginLink": "Sign in", // ── Home / Dashboard ── "home.welcome": "Welcome back, {name}", "home.placeholder": "This will be the Dashboard (StatCard / ActivityTimeline / ConnectedDevicesList); F6 will port it from local-tool.", "dashboard.title": "Dashboard", "dashboard.subtitle": "Manage your cloud-based Edge AI assets", "dashboard.models": "Models", "dashboard.devices": "Devices", "dashboard.connected": "Online devices", "dashboard.flashes": "Flashes", "dashboard.connectedDevices": "Online devices", "dashboard.noConnectedDevices": "No devices are online. Pair a Kneron device to start cloud inference.", "dashboard.recentActivity": "Recent activity", "dashboard.noActivity": "Nothing here yet. Activity appears after pairing, uploads, or inference runs.", "dashboard.quickActions": "Quick actions", "dashboard.browseModels": "Browse models", "dashboard.manageDevices": "Manage devices", "dashboard.uploadModel": "Upload model", "dashboard.pairDevice": "Pair device", "dashboard.empty.title": "No devices yet", "dashboard.empty.description": "Pair your first Kneron device to start running inference from anywhere.", "dashboard.empty.action": "Pair a device", "dashboard.activity.justNow": "just now", "dashboard.activity.minutesAgo": "{n} minutes ago", "dashboard.activity.hoursAgo": "{n} hours ago", "dashboard.activity.daysAgo": "{n} days ago", // ── Devices ── "devices.title": "Devices", "devices.subtitle": "Manage your Edge AI devices", "devices.type": "Type", "devices.firmware": "Firmware", "devices.flashedModel": "Flashed model", "devices.openWorkspace": "Open workspace", "devices.addMore": "Pair a new device", "devices.pairAction": "Pair a new device", "devices.empty.title": "No devices paired yet", "devices.empty.description": "Run local agent on your computer and complete pairing to access your Kneron devices from anywhere.", "devices.empty.action": "Pair your first device", "devices.empty.secondaryAction": "How pairing works", "devices.detail.id": "ID", "devices.detail.type": "Type", "devices.detail.firmware": "Firmware", "devices.detail.port": "Port", "devices.detail.deviceInfo": "Device info", "devices.detail.modelStatus": "Model status", "devices.detail.readyForInference": "Ready for inference", "devices.detail.noModelFlashed": "No model has been flashed", "devices.detail.pairedAt": "Paired at", "devices.detail.hostName": "Host", "devices.detail.lastSeen": "Last seen", "devices.detail.offlineBanner.title": "This device is offline", "devices.detail.offlineBanner.description": "Some actions are unavailable until local agent reconnects.", "devices.status.detected": "Detected", "devices.status.connecting": "Connecting", "devices.status.connected": "Connected", "devices.status.flashing": "Flashing", "devices.status.inferencing": "Inferencing", "devices.status.error": "Error", "devices.status.disconnected": "Disconnected", // ── Remote Device Badge ── "remote.status.online": "Online", "remote.status.offline": "Offline", "remote.status.reconnecting": "Reconnecting", "remote.status.error": "Connection error", "remote.status.unknown": "Unknown", "remote.lastSeenNever": "Never connected", "remote.lastSeen.justNow": "just now", "remote.lastSeen.minutesAgo": "{n} min ago", "remote.lastSeen.hoursAgo": "{n} h ago", // ── Models ── "models.title": "Models", "models.subtitle": "Manage Kneron models on the cloud", "models.size": "Size", "models.createdAt": "Created", "models.status.uploading": "Uploading", "models.status.scanning": "Scanning", "models.status.ready": "Ready", "models.status.rejected": "Rejected", "models.source.uploaded": "Uploaded", "models.source.preset": "Preset", "models.source.converted": "Converted", "models.filters.label": "Model filters", "models.filters.hardware": "Hardware", "models.filters.source": "Source", "models.filters.all": "All", "models.empty.title": "No models yet", "models.empty.description": "Upload your first .nef model to deploy it to any paired Kneron device.", "models.empty.action": "Upload your first model", "models.detail.description": "Description", "models.detail.version": "Version", "models.detail.checksum": "Checksum", "models.detail.supportedChips": "Supported chips", "models.detail.deployToDevice": "Deploy to device", // ── Model Upload Dialog ── "models.upload.button": "Upload model", "models.upload.dialog.title": "Upload model", "models.upload.dropzone.hint": "Format: .nef · Max 100 MB", "models.upload.selectedFile": "Choose file", "models.upload.field.name": "Model name", "models.upload.field.version": "Version", "models.upload.field.notes": "Notes (optional)", "models.upload.field.targetChip": "Target chip", "models.upload.action.cancel": "Cancel", "models.upload.action.start": "Start upload", "models.upload.action.remove": "Remove", "models.upload.uploading.title": "Uploading", "models.upload.uploading.hint": "Do not close this window or navigate away.", "models.upload.success.title": "Upload complete", "models.upload.success.scanHint": "The model is entering safety scan; it will be available once ready.", "models.upload.error.invalidType": "Only .nef files are supported, got {type}.", "models.upload.error.tooLarge": "File too large ({size}); max allowed is 100 MB.", "models.upload.error.requiredField": "{field} is required.", "models.upload.error.urlFailed": "Server is busy, please try again.", "models.upload.error.networkLost": "Network lost, upload paused.", "models.upload.toast.uploaded": "Model \"{name}\" uploaded.", // ── Model download (Phase 0.9 FAA delegated download) ── "models.action.download": "Download", "models.action.downloading": "Downloading…", "models.action.download.aria": "Download the model file to your device", "models.action.download.unsupportedTooltip": "Only converted models are downloadable in this phase", "models.download.toast.start": "Download started", "models.download.toast.hint": "If you don't see a download prompt, check your browser settings", "models.download.error.title": "Download failed", "models.download.error.model_not_found": "Model not found.", "models.download.error.forbidden": "You don't have permission to download this model.", "models.download.error.upload_not_supported": "Uploaded models are not downloadable in this phase.", "models.download.error.sign_failed": "Failed to obtain a download grant, please try again later.", "models.download.error.download_failed": "Failed to download from the file server, please try again later.", "models.download.error.network_error": "Network error, please check your connection and retry.", "models.download.error.timeout": "Download timed out, please try again later.", "models.download.error.busy": "A download is already in progress, please wait.", "models.download.error.unknown": "Download failed, please try again later.", // ── Workspace ── "workspace.title": "Workspace", "workspace.subtitle": "Select an online device to start inference", "workspace.empty.title": "No devices are online", "workspace.empty.description": "Pair a device and make sure the local agent is connected to the cloud.", "workspace.empty.action": "Go to devices", "workspace.header.backToDevices": "Back to devices", "workspace.header.title": "Workspace", "workspace.inference.start": "Start inference", "workspace.inference.stop": "Stop inference", "workspace.placeholder.cameraComingSoon": "Camera inference preview — F8 will wire up the MJPEG stream through the tunnel from local agent.", "workspace.offline.title": "Device went offline", "workspace.offline.description": "The connection to {deviceName} was lost; inference has been stopped.", "workspace.offline.backToList": "Back to devices", "workspace.tabs.camera": "Camera", "workspace.tabs.image": "Image (Phase 1)", "workspace.tabs.video": "Video (Phase 1)", "workspace.tabs.batch": "Batch (Phase 1)", // ── Settings ── "settings.title": "Settings", "settings.subtitle": "Manage preferences and cloud endpoints", "settings.tabs.general": "General", "settings.tabs.advanced": "Advanced", "settings.general.title": "Preferences", "settings.general.language": "Language", "settings.general.theme": "Theme", "settings.general.themeHint": "Automatically follow your system light / dark mode.", "settings.advanced.title": "Cloud endpoints", "settings.advanced.apiEndpoint": "API endpoint", "settings.advanced.apiEndpointHint": "Normal users should not change this; developers can switch to staging or localhost.", "settings.advanced.apiUrl": "Current API URL", "settings.advanced.wsUrl": "Current WebSocket URL", "settings.advanced.about": "About", "settings.advanced.version": "Version", "settings.advanced.platform": "Platform", // ── Pairing (F7) ── "pairing.title": "Pair a new device", "pairing.subtitle": "Connect your Kneron device to the cloud so you can operate it from anywhere.", "pairing.token.title": "Your pairing token", "pairing.step1.description": "Copy the token below and paste it into your local agent within 15 minutes.", "pairing.copy": "Copy", "pairing.copied": "Copied", "pairing.regenerate": "Regenerate", "pairing.timeRemaining": "{time} remaining", "pairing.generatedAt": "Generated at {time}", "pairing.token.expired.label": "This token has expired — please regenerate.", "pairing.regenerateConfirm.title": "Regenerate token?", "pairing.regenerateConfirm.description": "The old token will be invalidated immediately; the new one is valid for 15 minutes.", "pairing.security.warning": "This token is valid for 15 minutes — complete pairing now.", "pairing.security.oneTime": "Tokens are single-use and expire automatically after pairing.", "pairing.toast.copied": "Token copied — valid for 15 minutes.", "pairing.toast.generateFailed": "Could not generate token — please retry.", "pairing.toast.expiringSoon": "Token expiring soon — complete pairing or regenerate.", "pairing.toast.pairedSuccess": "Device {deviceName} paired successfully.", "pairing.toast.cliCopied": "CLI command copied.", "pairing.device.unknown": "Unknown device", "pairing.cli.title": "CLI example", "pairing.cli.description": "Start local agent on your computer and pass the token to the --relay-token flag.", "pairing.cli.copy": "Copy command", "pairing.cli.hint": "Once local agent connects to the cloud, this page detects it and forwards you to the device list.", "pairing.step3.waiting": "Waiting for local agent to connect…", "pairing.step3.elapsed": "Elapsed {time} (max 3 minutes)", "pairing.step3.hints.running": "Confirm local agent is running", "pairing.step3.hints.token": "Confirm the token was pasted without missing or extra characters", "pairing.step3.hints.network": "Confirm your network can reach the cloud endpoint", "pairing.step3.success": "Connected!", "pairing.step3.success.detected": "Detected device", "pairing.step3.failure.timeout": "Connection timeout", "pairing.step3.failure.reason": "No local agent connection within 3 minutes — agent may not be running.", "pairing.step3.failure.retry": "Check again", // ── Account (Phase 0.6 OIDC) ── // Design notes: // - Profile is read-only; edits go through the Innovedus Account Center // - "Delete account" stays as a disabled stub; copy directs users to Member Center "account.title": "Account settings", "account.subtitle": "Profile is managed by the Innovedus Account Center", "account.profile.title": "Profile", "account.profile.userId": "User ID", "account.profile.email": "Email", "account.profile.name": "Display name", "account.profile.namePlaceholder": "—", "account.profile.managedBy": "Your profile is managed by the Innovedus Account Center. To make changes, please go to the Innovedus Account Center.", "account.profile.editAtMemberCenter": "Open Innovedus Account Center", "account.profile.editDisabledHint": "Innovedus Account Center URL is not configured. Please contact the administrator.", "account.session.title": "Session", "account.session.description": "Signing out returns you to the login page. You will need to sign in again through the Innovedus Account Center.", "account.danger.title": "Danger zone", "account.danger.description": "Account deletion is handled at the Innovedus Account Center; visionA does not perform deletion directly.", "account.danger.deleteAccount": "Delete account", "account.danger.deleteAccount.tooltip": "Please handle this at the Innovedus Account Center.", // ── Conversion (Phase 0.8 — feature-converter-integration) ── // Spec: .autoflow/03-design/wireframes/wireframe-conversion.md §11 // PRD: .autoflow/02-prd/features/feature-converter-integration.md // Scope: 5 states (idle / uploading / processing / success / failed) + 6 error code translations + expired "conversion.title": "Convert", "conversion.subtitle": "Turn ONNX / TFLite models into .nef so they can run on Kneron edge devices.", // idle empty state "conversion.idle.heading": "No conversion in progress", "conversion.idle.description": "Upload an ONNX / TFLite model, pick a target Kneron chip, and we'll produce a flashable .nef file for you.", "conversion.idle.cta": "Start conversion", "conversion.idle.formats": "Supports .onnx / .tflite · max 500 MB", "conversion.idle.about.title": "About conversion", "conversion.idle.about.line1": "Only one conversion job per user at a time (across tabs).", "conversion.idle.about.line2": "Results are downloadable for 7 days, then automatically cleared.", "conversion.idle.about.line3": "Conversion typically takes 1–10 minutes depending on model size.", // Upload Dialog "conversion.upload.title": "Start conversion", "conversion.upload.description": "Upload a model, choose a target chip, and optionally attach reference images for better accuracy.", "conversion.upload.source.label": "Source model", "conversion.upload.source.dropzone": "Drag .onnx / .tflite here", "conversion.upload.source.or": "or", "conversion.upload.source.browse": "Choose file", "conversion.upload.source.formatHint": "Format: .onnx · .tflite · max 500 MB", "conversion.upload.source.remove": "Remove", "conversion.upload.name.label": "Job name (optional)", "conversion.upload.name.hint": "Display only; does not change output filename.", "conversion.upload.chip.label": "Target chip", "conversion.upload.refImages.label": "Reference images (optional)", "conversion.upload.refImages.dropzone": "Drag images here (optional)", "conversion.upload.refImages.hint": "Reference images can improve quantized accuracy (max 100 images, ≤ 10 MB each).", "conversion.upload.refImages.summary": "{count} reference images selected ({totalSize})", "conversion.upload.refImages.removeAll": "Remove all", "conversion.upload.cancel": "Cancel", "conversion.upload.start": "Start conversion", "conversion.upload.error.noFile": "Please choose a .onnx or .tflite file.", "conversion.upload.error.unsupported": "Unsupported format — please use ONNX or TFLite.", "conversion.upload.error.modelTooLarge": "Model exceeds the 500 MB limit; please use a smaller model.", "conversion.upload.error.noChip": "Please pick a target chip.", "conversion.upload.error.refTooLarge": "{filename} is over 10 MB — please remove or compress it.", "conversion.upload.error.refTooMany": "Reference images cannot exceed 100 files.", // uploading stage (inside Dialog) "conversion.uploading.title": "Uploading", "conversion.uploading.heading": "Uploading to visionA…", "conversion.uploading.progress": "{loaded} / {total} uploaded · {eta} remaining", "conversion.uploading.almostDone": "Almost done…", "conversion.uploading.warning": "Please don't close this tab — the upload will be aborted.", "conversion.uploading.cancel": "Cancel upload", "conversion.uploading.cancelConfirm": "Upload not finished — cancel anyway?", "conversion.uploading.tabTitle": "visionA Cloud · Uploading ({pct}%)", "conversion.uploading.toastCanceled": "Upload canceled.", "conversion.uploading.toastFailed": "Upload failed: {reason}", // F-T9 sub-3 / M1: upload failure toast hint // M1 fix: File objects can't live in the store (non-serializable / unsafe across unmounts); // chip / task name are preserved via store.formDraft, but the file itself must be re-selected. "conversion.toast.retryHint": "Your settings (chip / task name) are preserved — please re-select the file to retry.", "conversion.toast.networkError": "Network error — please check your connection and retry.", "conversion.uploading.toastStarted": "Conversion started (job #{shortJobId}).", // F-T5: ETA / cancel confirm / beforeunload (detailed keys) "conversion.uploading.subtitle": "Uploading model to visionA backend", "conversion.uploading.eta.computing": "Estimating time remaining…", "conversion.uploading.eta.almostDone": "Almost done…", "conversion.uploading.eta.format": "{eta} remaining", "conversion.uploading.progress.format": "{loaded} / {total}", "conversion.uploading.info": "Conversion will start automatically (typically 10–30 seconds).", "conversion.uploading.cancel.confirm.title": "Cancel conversion?", "conversion.uploading.cancel.confirm.message": "Upload is not finished — uploaded progress will be lost. Cancel anyway?", "conversion.uploading.cancel.confirm.yes": "Yes, cancel", "conversion.uploading.cancel.confirm.no": "Keep uploading", "conversion.uploading.warning.beforeunload": "Upload not finished — leaving will abort the upload.", "conversion.uploading.target": "Target: {chip}", "conversion.uploading.aria.cancel": "Cancel upload", "conversion.uploading.aria.progress": "Upload progress", "conversion.uploading.aria.status": "Uploaded {pct}%, {eta}", // processing stage "conversion.processing.title": "Convert", "conversion.processing.cardHeading": "In progress", "conversion.processing.statusBadge": "Converting", "conversion.processing.startedAgo": "Started {time}", "conversion.processing.stage1": "Upload complete", "conversion.processing.stage2": "Parsing model", "conversion.processing.stage3": "Compiling NEF", "conversion.processing.processing": "Processing…", "conversion.processing.hint": "Typically 1–10 minutes · You can leave this page; progress will resume when you return.", "conversion.processing.background.title": "Feel free to walk away", "conversion.processing.background.l1": "We poll progress in the background (every 5–10 seconds).", "conversion.processing.background.l2": "The tab title will notify you on completion.", "conversion.processing.background.l3": "Closing this page is fine — it will resume automatically.", "conversion.processing.queueLong": "Queue is currently long — you can come back later.", "conversion.processing.runLong": "This conversion is taking a while; still running.", "conversion.processing.pollFailed": "Couldn't fetch conversion status — please retry.", "conversion.processing.bannerActive": "A conversion was still running when you left.", "conversion.processing.bannerExisting": "You already have a conversion in progress — switched to that job.", // F-T9 sub-2: banner dismiss button a11y label "conversion.processing.bannerDismiss": "Dismiss notice", // F-T6: ProcessingView (queued / running shared UI) "conversion.processing.subtitle": "Conversion in progress — please keep this page open", "conversion.processing.queued": "Queued…", "conversion.processing.stage.onnx": "Parsing model", "conversion.processing.stage.bie": "Quantize & compile", "conversion.processing.stage.nef": "Compile NEF", "conversion.processing.stage.status.completed": "Done", "conversion.processing.stage.status.current": "In progress", "conversion.processing.stage.status.pending": "Pending", "conversion.processing.stage.aria.completed": "{name} (completed)", "conversion.processing.stage.aria.current": "{name} (in progress)", "conversion.processing.stage.aria.pending": "{name} (pending)", "conversion.processing.eta.pending": "Please wait", "conversion.processing.eta.computing": "Estimating time remaining", "conversion.processing.expiryHint": "Job will be auto-deleted in 7 days — please download or add it to your model library before then.", "conversion.processing.tabTitle.prefix": "(Converting) ", "conversion.processing.aria.progressIndeterminate": "Conversion in progress; remaining time unknown", "conversion.processing.aria.queueProgress": "Queued, waiting for conversion to start", "conversion.processing.targetChipPrefix": "→", // active job hint (also shown on idle) "conversion.busy.title": "You already have a conversion in progress", "conversion.busy.cta": "View progress", // success "conversion.success.heading": "Conversion complete", "conversion.success.summary.chip": "Target chip", "conversion.success.summary.size": "Output size", "conversion.success.summary.duration": "Duration", "conversion.success.summary.checksum": "checksum", "conversion.success.summary.jobId": "Job", "conversion.success.nextStep": "What's next?", "conversion.success.import.title": "Add to model library", "conversion.success.import.description": "You can deploy it from the model library to any {chip} device.", "conversion.success.import.cta": "Add to library", "conversion.success.import.dialog.title": "Add to model library", "conversion.success.import.dialog.description": "Add this conversion result to the model library so you can deploy it to {chip} devices.", "conversion.success.import.dialog.nameLabel": "Model name", "conversion.success.import.dialog.nameHint": "Display name in the model library; up to 100 characters; cannot contain / or \\.", "conversion.success.import.dialog.nameError.required": "Please enter a model name.", "conversion.success.import.dialog.nameError.tooLong": "Model name must be 100 characters or fewer.", "conversion.success.import.dialog.nameError.invalidChars": "Model name cannot contain / or \\.", "conversion.success.import.dialog.descLabel": "Description (optional)", "conversion.success.import.dialog.sourceLabel": "Source", "conversion.success.import.dialog.sourceValue": "Conversion (job #{shortJobId})", "conversion.success.import.dialog.confirm": "Add to library", "conversion.success.import.dialog.cancel": "Cancel", "conversion.success.import.processing": "Processing…", "conversion.success.import.toastDone": "Added to model library.", "conversion.success.import.toastDoneAction": "Open model library →", "conversion.success.import.toastDup": "This job has already been added to the library.", "conversion.success.import.toastDupAction": "View existing model →", "conversion.success.import.statusDone": "✓ Added (open it →)", "conversion.success.import.errorGeneric": "Couldn't add to model library; please try again.", "conversion.success.import.aria.cta": "Add to model library (opens a confirmation dialog)", "conversion.success.download.title": "Download .nef", "conversion.success.description": "{source} has been converted into a .nef compatible with {chip}.", "conversion.success.summary.outputFile": "Output file", "conversion.success.summary.notAvailable": "—", "conversion.success.download.description": "Save it locally to use elsewhere.", "conversion.success.download.cta": "Download", "conversion.success.download.preparing": "Preparing download…", "conversion.success.download.toastStart": "Download started.", "conversion.success.download.toastHint": "If no download prompt appears, check your browser settings.", "conversion.success.download.toastFail": "Couldn't fetch download link.", "conversion.success.download.aria.cta": "Download .nef file to your computer", "conversion.success.download.aria.disabled": "Download link expired; start a new conversion", "conversion.success.expiry": "This result will be auto-deleted in {time}; please finish using it before then.", "conversion.success.expiry.expired": "This conversion result has expired.", "conversion.success.expiry.remaining.daysHours": "{days}d {hours}h", "conversion.success.expiry.remaining.daysOnly": "{days}d", "conversion.success.expiry.remaining.hoursMinutes": "{hours}h {minutes}m", "conversion.success.expiry.remaining.hoursOnly": "{hours}h", "conversion.success.expiry.remaining.minutes": "{minutes}m", "conversion.success.startNew": "Start new conversion", // failed "conversion.failed.heading": "Conversion failed", "conversion.failed.errorCode": "Error code", "conversion.failed.suggestionsTitle": "Things you can try:", "conversion.failed.retry": "Try again", "conversion.failed.backToModels": "Back to models", "conversion.failed.contactSupport": "If this keeps happening, copy the job ID and contact support.", "conversion.failed.copyJobId": "Copy job ID", "conversion.failed.toastJobIdCopied": "Job ID copied.", // F-T8 — FailedView "conversion.failed.aria.alert": "Conversion failure notice", "conversion.failed.jobIdLabel": "Job ID", "conversion.failed.summary.failedSuffix": " (failed)", "conversion.failed.aria.retry": "Reset and start a new conversion", // error code translations (mirrors zh-Hant; one key per suggestion line) "conversion.error.UNSUPPORTED_FORMAT.message": "This model format isn't supported — please use ONNX / TFLite.", "conversion.error.UNSUPPORTED_FORMAT.suggestion1": "Verify file extension.", "conversion.error.UNSUPPORTED_FORMAT.suggestion2": "Use a standard export tool.", "conversion.error.INVALID_CHECKSUM.message": "File was corrupted in transit — please re-upload.", "conversion.error.INVALID_CHECKSUM.suggestion1": "Restart the upload.", "conversion.error.QUANTIZATION_FAILED.message": "Model contains unsupported operators and can't be quantized for the target chip.", "conversion.error.QUANTIZATION_FAILED.suggestion1": "Simplify the model.", "conversion.error.QUANTIZATION_FAILED.suggestion2": "Remove custom ops.", "conversion.error.QUANTIZATION_FAILED.suggestion3": "Use a smaller input shape.", "conversion.error.MODEL_TOO_LARGE.message": "Model exceeds the 500 MB limit.", "conversion.error.MODEL_TOO_LARGE.suggestion1": "Use a smaller model.", "conversion.error.MODEL_TOO_LARGE.suggestion2": "Try pruning / quantization first.", "conversion.error.QUOTA_EXCEEDED.message": "System is busy right now — please try again later.", "conversion.error.QUOTA_EXCEEDED.suggestion1": "Wait 5 minutes and retry.", "conversion.error.unknown.message": "Conversion failed. If it keeps happening, contact support.", "conversion.error.unknown.suggestion1": "Copy the job ID and report it to support.", // expired / not-found "conversion.expired.heading": "This conversion result has expired", "conversion.expired.description": "Conversion results are kept for 7 days; this one has been auto-cleared.", // F-T9 sub-1: ExpiredView extra description — explain how to recover "conversion.expired.subDescription": "To get a new conversion result, please submit the model again.", // F-T9 sub-1: ExpiredView a11y "conversion.expired.aria.alert": "Conversion result has expired notice", "conversion.expired.aria.startNew": "Reset and start a new conversion", "conversion.expired.startNew": "Start new conversion", // mobile hint "conversion.mobileHint": "Uploading large models on mobile can be unreliable; we recommend a desktop browser.", // ── Clusters (F7 stub) ── "clusters.title": "Clusters", "clusters.subtitle": "Combine multiple Kneron devices into a parallel inference cluster.", "clusters.create": "Create cluster", "clusters.empty.title": "Cluster inference — coming in Phase 1", "clusters.empty.description": "Phase 1 will port the POC’s multi-device parallel inference and degrade handling to the cloud.", "clusters.phase1Badge": "Coming in Phase 1", "clusters.phase1Toast": "Cluster creation arrives in Phase 1.", };