Files
afilmory/locales/dashboard/en.json
Innei 0da12eb301 feat: implement drag-and-drop file upload feature in photo library
- Added PhotoLibraryDropUpload component to handle file drag-and-drop uploads.
- Integrated file type validation to support images and specific video formats.
- Implemented user feedback through modals and toasts for unsupported file types.
- Updated localization files to include new strings for drag-and-drop functionality in English and Chinese.
- Modified PhotoLibraryTab to include the new upload component.

Signed-off-by: Innei <tukon479@gmail.com>
2025-12-14 15:37:30 +08:00

967 lines
67 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"access-denied.default-reason": "You do not have permission to access this page.",
"analytics.page.description": "Track your photo collection statistics and trends.",
"analytics.page.title": "Analytics",
"analytics.sections.devices.description": "Popular capture devices derived from EXIF metadata.",
"analytics.sections.devices.empty": "No device statistics yet.",
"analytics.sections.devices.error": "Unable to load device data. Please try again later.",
"analytics.sections.devices.title": "Top Devices",
"analytics.sections.storage.current": "Added this month",
"analytics.sections.storage.delta.compare": "{{delta}} vs last month",
"analytics.sections.storage.delta.equal": "Same as last month",
"analytics.sections.storage.delta.first": "First recorded usage",
"analytics.sections.storage.description": "Capacity breakdown by storage provider.",
"analytics.sections.storage.empty": "No storage usage data.",
"analytics.sections.storage.error": "Unable to load storage usage. Please try again later.",
"analytics.sections.storage.photos": "Photos",
"analytics.sections.storage.provider-meta": "{{percent}}% · {{photoCount}} photos",
"analytics.sections.storage.title": "Storage Usage",
"analytics.sections.storage.total": "Total usage",
"analytics.sections.tags.description": "Most used tags from recent uploads.",
"analytics.sections.tags.empty": "No tag statistics yet.",
"analytics.sections.tags.error": "Unable to load tag data. Please try again later.",
"analytics.sections.tags.title": "Popular Tags",
"analytics.sections.upload.best": "Best month",
"analytics.sections.upload.compare-equal": "Same as last month",
"analytics.sections.upload.current": "Uploads this month",
"analytics.sections.upload.description": "Uploads over the past 12 months.",
"analytics.sections.upload.empty": "No upload data yet.",
"analytics.sections.upload.error": "Unable to load upload trends. Please try again later.",
"analytics.sections.upload.first-record": "First recorded uploads",
"analytics.sections.upload.growth-equal": "Same as last month",
"analytics.sections.upload.title": "Upload Trends",
"analytics.sections.upload.tooltip": "{{month}} · {{value}} photos",
"analytics.sections.upload.total": "Total uploads",
"analytics.units.photos": "{{value}} photos",
"app.name": "Afilmory Dashboard",
"auth.registration.common.disabled": "Disabled",
"auth.registration.common.enabled": "Enabled",
"auth.registration.footer.back": "Back",
"auth.registration.footer.continue": "Continue",
"auth.registration.footer.create_workspace": "Create workspace",
"auth.registration.header.step_indicator": "Step {{current}} of {{total}}",
"auth.registration.sidebar.create_tenant": "Create your tenant",
"auth.registration.sidebar.progress": "Progress",
"auth.registration.sidebar.workspace_setup": "Workspace Setup",
"auth.registration.steps.login.continue_setup": "Continue setup",
"auth.registration.steps.login.continue_with": "Continue with",
"auth.registration.steps.login.description": "Sign in with your identity provider to continue.",
"auth.registration.steps.login.intro_text": "Afilmory is a modern SaaS <0>photo gallery platform</0> that auto-syncs your libraries, renders them with WebGL, and powers tenant workspaces. The dashboard is the command center for those capabilities, so connecting your account lets us personalize the workspace setup for your team.",
"auth.registration.steps.login.platform_link": "photo gallery platform",
"auth.registration.steps.login.provider_hint": "Choose your provider below. After completing the sign-in flow you'll return here automatically.",
"auth.registration.steps.login.sign_in_description": "Use your organization's identity provider to create a workspace. We'll use your profile details to set up the initial administrator.",
"auth.registration.steps.login.sign_in_title": "Sign in to continue",
"auth.registration.steps.login.signed_in_as": "You're signed in as",
"auth.registration.steps.login.title": "Connect account",
"auth.registration.steps.review.description": "Verify everything looks right and accept the terms before provisioning the workspace.",
"auth.registration.steps.review.description_confirm": "Double-check the details below. You can go back to make adjustments before creating the workspace.",
"auth.registration.steps.review.label_admin_email": "Administrator email",
"auth.registration.steps.review.label_admin_name": "Administrator name",
"auth.registration.steps.review.label_workspace_name": "Workspace name",
"auth.registration.steps.review.label_workspace_slug": "Workspace slug",
"auth.registration.steps.review.policies_description": "Creating a workspace means you agree to comply with our usage guidelines and privacy practices.",
"auth.registration.steps.review.privacy_link": "Privacy Policy",
"auth.registration.steps.review.section_policies": "Policies",
"auth.registration.steps.review.section_site_details": "Site details",
"auth.registration.steps.review.terms_agree_pre": "I agree to the",
"auth.registration.steps.review.terms_and": "and",
"auth.registration.steps.review.terms_link": "Terms of Service",
"auth.registration.steps.review.title": "Review & confirm",
"auth.registration.steps.review.title_confirm": "Confirm workspace configuration",
"auth.registration.steps.site.branding_description": "These details appear on your public gallery, metadata, and social sharing cards. You can change them later from the dashboard.",
"auth.registration.steps.site.branding_title": "Site branding",
"auth.registration.steps.site.description": "Configure the public gallery branding your visitors will see.",
"auth.registration.steps.site.error_loading": "We couldn't load the site configuration schema from the server. Refresh the page or contact support.",
"auth.registration.steps.site.title": "Site information",
"auth.registration.steps.workspace.basics_description": "This information appears in navigation, invitations, and other tenant-facing areas.",
"auth.registration.steps.workspace.basics_title": "Workspace basics",
"auth.registration.steps.workspace.description": "Give your workspace a recognizable name and choose a slug for tenant URLs.",
"auth.registration.steps.workspace.label_name": "Workspace name",
"auth.registration.steps.workspace.label_slug": "Workspace slug",
"auth.registration.steps.workspace.slug_helper": "Lowercase letters, numbers, and hyphen are allowed. We'll ensure the slug is unique.",
"auth.registration.steps.workspace.slug_locked_helper": "Workspace slug follows the current subdomain and cannot be changed in this flow.",
"auth.registration.steps.workspace.title": "Workspace details",
"auth.registration.wizard.have_account": "Already have an account?",
"auth.registration.wizard.sign_in": "Sign in",
"auth.registration.wizard.toast.sign_in_required": "Please sign in to continue",
"auth.registration.wizard.toast.validation_error": "Error in {{issues}}",
"auth.social.empty.description": "Super admins have not enabled any third-party login methods. This tenant cannot bind OAuth accounts yet.",
"auth.social.empty.title": "No OAuth providers configured",
"auth.social.error.accounts": "Unable to fetch binding status",
"auth.social.error.providers": "Unable to load available OAuth providers",
"auth.social.provider.connect": "Link {{provider}}",
"auth.social.provider.connected": "Linked · {{time}}",
"auth.social.provider.connecting": "Redirecting…",
"auth.social.provider.disconnect": "Disconnect",
"auth.social.provider.disconnecting": "Disconnecting…",
"auth.social.provider.last-warning": "At least one sign-in method must remain linked.",
"auth.social.provider.unconnected": "Not linked yet. Use the button below to authorize.",
"auth.social.section.description": "Link a provider to log in with that account and sync basic profile data. Disconnecting does not delete the dashboard account.",
"auth.social.section.label": "Sign-in methods",
"auth.social.section.title": "OAuth connections",
"auth.social.toast.connect-failure": "Failed to start linking with {{provider}}",
"auth.social.toast.disconnect-failure": "Failed to disconnect",
"auth.social.toast.disconnect-success": "Disconnected from {{provider}}",
"blocker.unsaved.before-unload": "You have unsaved changes. Are you sure you want to leave?",
"blocker.unsaved.cancel": "Stay on page",
"blocker.unsaved.confirm": "Leave anyway",
"blocker.unsaved.description": "You have unsaved edits. Leaving this page will discard them. Continue?",
"blocker.unsaved.title": "Unsaved changes",
"builder-settings.button.loading": "Saving…",
"builder-settings.button.save": "Save changes",
"builder-settings.error.loading": "Unable to load builder settings: {{reason}}",
"builder-settings.message.dirty": "You have unsaved changes",
"builder-settings.message.error": "Failed to save settings: {{reason}}",
"builder-settings.message.idle": "All settings are up to date",
"builder-settings.message.saved": "Settings saved successfully",
"builder-settings.message.saving": "Saving builder settings…",
"builder-settings.message.unknown-error": "Unknown error",
"common.retry-later": "Please try again later.",
"common.unknown": "unknown",
"common.unknown-error": "Unknown error",
"dashboard.overview.activity.empty": "No recent activity. Upload photos to see updates here.",
"dashboard.overview.activity.error": "Unable to load activity data. Please try again later.",
"dashboard.overview.activity.id-label": "ID:",
"dashboard.overview.activity.no-preview": "No Preview",
"dashboard.overview.activity.size-unknown": "Size unknown",
"dashboard.overview.activity.subtitle": "Showing the latest {{count}} uploads and sync events",
"dashboard.overview.activity.subtitle-empty": "No uploads yet—add your first photo!",
"dashboard.overview.activity.taken-at": "Taken {{time}}",
"dashboard.overview.activity.uploaded-at": "Uploaded {{time}}",
"dashboard.overview.page.description": "Monitor library health and recent sync activity.",
"dashboard.overview.page.title": "Dashboard",
"dashboard.overview.section.activity.title": "Recent activity",
"dashboard.overview.stats.month.helper.equal": "Same as last month",
"dashboard.overview.stats.month.helper.first": "Uploads recorded for the first time",
"dashboard.overview.stats.month.helper.less": "{{difference}} fewer than last month",
"dashboard.overview.stats.month.helper.more": "{{difference}} more than last month",
"dashboard.overview.stats.month.label": "Uploads this month",
"dashboard.overview.stats.storage.helper.empty": "No photos yet; storage usage is 0",
"dashboard.overview.stats.storage.helper.with-photos": "Average {{average}} per photo",
"dashboard.overview.stats.storage.label": "Storage used",
"dashboard.overview.stats.sync.helper": "Pending {{pending}} | Conflicts {{conflicts}}",
"dashboard.overview.stats.sync.helper-empty": "No sync jobs yet",
"dashboard.overview.stats.sync.label": "Sync completion",
"dashboard.overview.stats.total.helper": "{{value}} photos",
"dashboard.overview.stats.total.label": "Total photos",
"dashboard.overview.status.conflict": "Needs attention",
"dashboard.overview.status.pending": "Processing",
"dashboard.overview.status.synced": "Synced",
"dashboard.overview.time.unknown": "Unknown time",
"data-management.delete.badge": "Account purge (irreversible)",
"data-management.delete.button": "Delete account permanently",
"data-management.delete.description": "This removes the tenant, photo records, sync logs, and member permissions from the database. Members are signed out immediately and the operation cannot be undone. Three confirmations are required to avoid mistakes.",
"data-management.delete.error.fallback": "Failed to delete the tenant. Please try again later.",
"data-management.delete.error.title": "Operation failed",
"data-management.delete.loading": "Destroying…",
"data-management.delete.note": "To reuse the service later, register a new tenant and re-upload your assets. Object storage files remain, but all database references are removed.",
"data-management.delete.step1.cancel": "Cancel",
"data-management.delete.step1.confirm": "Continue",
"data-management.delete.step1.description": "Deleting will immediately clear all tenant data and sign out every member. This flow has three confirmations for safety.",
"data-management.delete.step1.title": "Delete account (Step 1/3)",
"data-management.delete.step2.cancel": "Cancel",
"data-management.delete.step2.confirm": "I understand the risk",
"data-management.delete.step2.description": "This permanently removes photos, settings, sync logs, and member permissions for this tenant.",
"data-management.delete.step2.title": "Second confirmation: remove entire account",
"data-management.delete.step3.cancel": "Back",
"data-management.delete.step3.confirm": "Delete permanently",
"data-management.delete.step3.description": "Type DELETE to confirm. This will log out all members and remove unrecoverable data immediately.",
"data-management.delete.step3.error.description": "Please enter DELETE to continue.",
"data-management.delete.step3.error.title": "Confirmation failed",
"data-management.delete.step3.placeholder": "DELETE",
"data-management.delete.step3.title": "Final confirmation: permanently delete account",
"data-management.delete.success.description": "All data for this tenant has been removed and members were signed out.",
"data-management.delete.success.title": "Tenant deleted",
"data-management.delete.title": "Delete current tenant and data",
"data-management.summary.badge": "Current data overview",
"data-management.summary.description": "Statistics are derived from database records only and exclude original files in storage.",
"data-management.summary.error": "Unable to load statistics. Please try again later.",
"data-management.summary.stats.conflicts.chip": "Needs review",
"data-management.summary.stats.conflicts.label": "Conflicts",
"data-management.summary.stats.pending.chip": "Queued",
"data-management.summary.stats.pending.label": "Pending",
"data-management.summary.stats.synced.chip": "Healthy",
"data-management.summary.stats.synced.label": "Synced",
"data-management.summary.stats.total.chip": "All",
"data-management.summary.stats.total.label": "Total records",
"data-management.summary.title": "Photo table status",
"data-management.truncate.badge": "Dangerous action",
"data-management.truncate.button": "Clear database records",
"data-management.truncate.description": "Delete every photo record from the database while keeping the original storage files. Useful for resolving inconsistencies or migrations.",
"data-management.truncate.error.fallback": "Unable to clear database records. Please try again later.",
"data-management.truncate.error.title": "Cleanup failed",
"data-management.truncate.loading": "Cleaning…",
"data-management.truncate.note": "After this action finishes, run Photo Sync again to rebuild the database and manifest from storage.",
"data-management.truncate.prompt.cancel": "Cancel",
"data-management.truncate.prompt.confirm": "Clear now",
"data-management.truncate.prompt.description": "This removes all photo records from the database but keeps the original objects in storage. You must run Photo Sync afterward.",
"data-management.truncate.prompt.title": "Confirm clearing photo tables?",
"data-management.truncate.success.deleted": "Marked {{count}} photo records for deletion.",
"data-management.truncate.success.empty": "No records needed cleanup.",
"data-management.truncate.success.title": "Database cleared",
"data-management.truncate.title": "Clear photo tables",
"error.boundary.description": "We encountered an unexpected error",
"error.boundary.go-back": "Go Back",
"error.boundary.help": "If this problem persists, please report it to our team.",
"error.boundary.reload": "Reload Application",
"error.boundary.report": "Report on GitHub",
"error.boundary.title": "Something went wrong",
"errors.request.generic": "Request failed. Please try again later.",
"header.plan.badge": "Plan",
"nav.analytics": "Analytics",
"nav.comments": "Comments",
"nav.library": "Library",
"nav.overview": "Overview",
"nav.photos": "Photos",
"nav.settings": "Settings",
"nav.users": "Users",
"no-access.back-to-login": "Back to Login",
"no-access.description": "You dont have the necessary permissions to access this feature. Contact your workspace admin or switch to an account with access.",
"no-access.request-path": "Request path:",
"no-access.retry": "Try Again",
"no-access.title.forbidden": "Permission denied",
"no-access.title.unavailable": "Access unavailable",
"photos.actions.conflict": "Conflict",
"photos.actions.delete": "Deleted",
"photos.actions.error": "Error",
"photos.actions.insert": "Inserted",
"photos.actions.noop": "Skipped",
"photos.actions.update": "Updated",
"photos.conflict.generic": "Conflict",
"photos.conflict.id.description": "Multiple objects share the same photo ID. Choose the version to keep.",
"photos.conflict.id.label": "Photo ID conflict",
"photos.conflict.metadata.description": "Storage object metadata differs from the database record. Decide which source should win.",
"photos.conflict.metadata.label": "Metadata mismatch",
"photos.conflict.missing.description": "Record exists in the database but the storage object is no longer accessible.",
"photos.conflict.missing.label": "Missing in storage",
"photos.library.actions.all-selected": "All selected",
"photos.library.actions.clear-selection": "Clear selection",
"photos.library.actions.delete": "Delete",
"photos.library.actions.edit-tags": "Edit tags",
"photos.library.actions.select-all": "Select all",
"photos.library.actions.selected-count": "{{count}} selected",
"photos.library.actions.upload": "Upload files",
"photos.library.actions.upload-short": "Upload",
"photos.library.card.delete": "Delete asset",
"photos.library.card.device-unknown": "Unknown device",
"photos.library.card.edit-tags": "Edit tags",
"photos.library.card.no-preview": "Preview unavailable",
"photos.library.card.select": "Select",
"photos.library.card.selected": "Selected",
"photos.library.card.size-unknown": "Size unknown",
"photos.library.card.view-exif": "View EXIF",
"photos.library.delete.cancel": "Cancel",
"photos.library.delete.confirm": "Delete",
"photos.library.delete.description": "This action cannot be undone. Continue deleting “{{name}}”? Enable the option below to also remove the remote storage file.",
"photos.library.delete.option.description": "When checked, the remote originals and thumbnails will be removed as well.",
"photos.library.delete.option.title": "Also delete storage files",
"photos.library.delete.title": "Delete this asset?",
"photos.library.dnd.description": "Release to review and start uploading.",
"photos.library.dnd.disabled": "Uploading is in progress. Please try again later.",
"photos.library.dnd.title": "Drop files to upload",
"photos.library.dnd.unsupported": "No supported files were detected.",
"photos.library.empty.description": "Use the upload button to add new photos to your library.",
"photos.library.empty.title": "No photos yet",
"photos.library.exif.empty": "No EXIF data is available for this asset.",
"photos.library.exif.file": "File: {{value}}",
"photos.library.exif.rows.altitude": "Altitude",
"photos.library.exif.rows.altitude-below": "{{value}} m (below sea level)",
"photos.library.exif.rows.altitude-value": "{{value}} m",
"photos.library.exif.rows.aperture": "Aperture",
"photos.library.exif.rows.aspect-ratio": "Aspect ratio",
"photos.library.exif.rows.author": "Author",
"photos.library.exif.rows.brightness": "Brightness value",
"photos.library.exif.rows.captured-at": "Captured at",
"photos.library.exif.rows.color-space": "Color space",
"photos.library.exif.rows.copyright": "Copyright",
"photos.library.exif.rows.device": "Camera",
"photos.library.exif.rows.eq-focal-length": "35mm equivalent focal length",
"photos.library.exif.rows.exposure-compensation": "Exposure compensation",
"photos.library.exif.rows.exposure-mode": "Exposure mode",
"photos.library.exif.rows.exposure-program": "Exposure program",
"photos.library.exif.rows.file-format": "Format",
"photos.library.exif.rows.file-size": "File size",
"photos.library.exif.rows.flash": "Flash",
"photos.library.exif.rows.focal-length": "Focal length",
"photos.library.exif.rows.iso": "ISO",
"photos.library.exif.rows.latitude": "Latitude",
"photos.library.exif.rows.lens": "Lens",
"photos.library.exif.rows.light-source": "Light source",
"photos.library.exif.rows.longitude": "Longitude",
"photos.library.exif.rows.megapixels": "Megapixels",
"photos.library.exif.rows.metering-mode": "Metering mode",
"photos.library.exif.rows.photo-id": "Photo ID",
"photos.library.exif.rows.rating": "Rating",
"photos.library.exif.rows.resolution": "Resolution",
"photos.library.exif.rows.scale-factor": "35mm scale factor",
"photos.library.exif.rows.scene-type": "Scene type",
"photos.library.exif.rows.sensor": "Sensor",
"photos.library.exif.rows.shutter": "Shutter speed",
"photos.library.exif.rows.software": "Software",
"photos.library.exif.rows.time-offset": "Time offset",
"photos.library.exif.rows.timezone": "Time zone",
"photos.library.exif.rows.timezone-source": "Time zone source",
"photos.library.exif.rows.title": "Title",
"photos.library.exif.rows.white-balance": "White balance",
"photos.library.exif.sections.basic": "Basic Info",
"photos.library.exif.sections.capture": "Capture Settings",
"photos.library.exif.sections.fuji": "Fujifilm Recipe",
"photos.library.exif.sections.location": "Location",
"photos.library.exif.sections.metadata": "Metadata",
"photos.library.sort.by-captured": "Sort by capture time",
"photos.library.sort.by-uploaded": "Sort by uploaded time",
"photos.library.sort.order-asc": "Oldest first",
"photos.library.sort.order-desc": "Newest first",
"photos.library.tags.modal.asset-count": "{{count}} assets",
"photos.library.tags.modal.cancel": "Cancel",
"photos.library.tags.modal.description.multiple": "All selected assets will receive the same tags. Tags also determine the remote storage path.",
"photos.library.tags.modal.description.single": "Tags determine the remote storage path. Moving tags will relocate original files and Live Photo videos accordingly.",
"photos.library.tags.modal.input": "Type a tag and press Enter, or select from suggested tags",
"photos.library.tags.modal.no-selection": "No asset selected",
"photos.library.tags.modal.path.hint": "Based on tag order",
"photos.library.tags.modal.path.preview": "New storage path preview",
"photos.library.tags.modal.path.sample": "Sample path (first item)",
"photos.library.tags.modal.save": "Save",
"photos.library.tags.modal.saving": "Saving…",
"photos.library.tags.modal.title": "Edit tags for “{{name}}”",
"photos.library.tags.toast.error": "Failed to update tags",
"photos.library.tags.toast.error-description": "Please try again later.",
"photos.library.tags.toast.multi-success": "Updated tags for {{count}} assets",
"photos.library.tags.toast.single-success": "Tags updated",
"photos.library.tags.toast.success-description": "Storage paths have been updated for the new tag structure.",
"photos.page.description": "Sync and manage photo assets on the server.",
"photos.page.title": "Photo Library",
"photos.storage.managed.actions.cancel": "Cancel managed storage",
"photos.storage.managed.actions.current": "Current plan",
"photos.storage.managed.actions.loading": "Updating…",
"photos.storage.managed.actions.make-active": "Make active",
"photos.storage.managed.actions.make-inactive": "Make inactive",
"photos.storage.managed.actions.manage": "Manage billing",
"photos.storage.managed.actions.retry": "Try again",
"photos.storage.managed.actions.subscribe": "Subscribe",
"photos.storage.managed.actions.subscribed": "Subscribed",
"photos.storage.managed.actions.switch": "Switch to this plan",
"photos.storage.managed.actions.upgrade": "Upgrade",
"photos.storage.managed.capacity.label": "Storage capacity: {{value}}",
"photos.storage.managed.capacity.unknown": "Capacity information is not available.",
"photos.storage.managed.capacity.unlimited": "Unlimited storage capacity",
"photos.storage.managed.description": "Subscribe to managed storage plans powered by the platforms shared provider—no self-hosted bucket required.",
"photos.storage.managed.empty": "No managed storage plans are currently available.",
"photos.storage.managed.error.load": "Failed to load managed storage plans.",
"photos.storage.managed.price.free": "Included in your current plan",
"photos.storage.managed.price.label": "{{price}} / month",
"photos.storage.managed.provider": "Backed by provider {{provider}}",
"photos.storage.managed.title": "Managed Storage",
"photos.storage.managed.toast.checkout-failure": "Unable to start checkout, please try again.",
"photos.storage.managed.toast.checkout-unavailable": "Managed storage checkout is unavailable right now.",
"photos.storage.managed.toast.error": "Failed to update managed storage: {{reason}}",
"photos.storage.managed.toast.missing-checkout-url": "Checkout URL is missing.",
"photos.storage.managed.toast.missing-portal-url": "Portal URL is missing.",
"photos.storage.managed.toast.portal-failure": "Unable to open billing portal, please try again.",
"photos.storage.managed.toast.success": "Managed storage plan updated.",
"photos.storage.managed.unavailable": "Managed storage hasnt been enabled for this workspace yet.",
"photos.sync.actions.button.apply": "Sync photos",
"photos.sync.actions.button.preview": "Preview sync",
"photos.sync.actions.toast.apply-success": "Photo sync completed",
"photos.sync.actions.toast.error-description": "Photo sync failed. Please try again later.",
"photos.sync.actions.toast.error-title": "Sync failed",
"photos.sync.actions.toast.preview-success": "Preview sync finished",
"photos.sync.actions.toast.success-description": "Inserted {{inserted}} · Updated {{updated}} · Conflicts {{conflicts}} · Errors {{errors}}",
"photos.sync.conflicts.actions.all-database": "Set all to database",
"photos.sync.conflicts.actions.all-storage": "Set all to storage",
"photos.sync.conflicts.actions.clear-selection": "Clear selection",
"photos.sync.conflicts.actions.hide-details": "Hide details",
"photos.sync.conflicts.actions.open-storage": "Open",
"photos.sync.conflicts.actions.prefer-database": "Keep database",
"photos.sync.conflicts.actions.prefer-storage": "Keep storage",
"photos.sync.conflicts.actions.selected-database": "Apply database to selected",
"photos.sync.conflicts.actions.selected-storage": "Apply storage to selected",
"photos.sync.conflicts.actions.view-details": "View details",
"photos.sync.conflicts.actions.view-original": "View original",
"photos.sync.conflicts.description": "These conflicts need manual confirmation. Select multiple entries to resolve faster.",
"photos.sync.conflicts.info.conflict-key": "Conflict key:",
"photos.sync.conflicts.info.first-detected": "Detected: {{time}}",
"photos.sync.conflicts.info.last-updated": "Last updated: {{time}}",
"photos.sync.conflicts.info.photo-id-fallback": "Photo ID missing",
"photos.sync.conflicts.info.storage-key": "Storage key:",
"photos.sync.conflicts.preview.common.dimensions": "Dimensions:",
"photos.sync.conflicts.preview.common.id": "ID:",
"photos.sync.conflicts.preview.common.size": "Size:",
"photos.sync.conflicts.preview.common.updated-at": "Updated:",
"photos.sync.conflicts.preview.database.empty": "No database record available",
"photos.sync.conflicts.preview.database.title": "Database record",
"photos.sync.conflicts.preview.storage.key": "Key:",
"photos.sync.conflicts.preview.storage.title": "Storage object",
"photos.sync.conflicts.prompts.bulk": "Resolve {{scope}} and {{strategy}}?",
"photos.sync.conflicts.prompts.cancel": "Cancel",
"photos.sync.conflicts.prompts.confirm": "Confirm",
"photos.sync.conflicts.prompts.scope-all": "all pending conflicts",
"photos.sync.conflicts.prompts.scope-selected": "the {{count}} selected conflicts",
"photos.sync.conflicts.prompts.single": "Resolve conflict {{identifier}} and {{strategy}}?",
"photos.sync.conflicts.prompts.title": "Confirm action",
"photos.sync.conflicts.selection.clear": "Clear selection",
"photos.sync.conflicts.selection.none": "No items selected",
"photos.sync.conflicts.selection.selected": "{{count}} selected",
"photos.sync.conflicts.strategy.database": "keep database version",
"photos.sync.conflicts.strategy.storage": "keep storage version",
"photos.sync.conflicts.title": "Pending conflicts",
"photos.sync.conflicts.toast.no-original": "No original asset preview is available for this record.",
"photos.sync.conflicts.toast.none": "No conflicts to resolve right now.",
"photos.sync.conflicts.toast.open-storage-failed": "Unable to open storage object",
"photos.sync.conflicts.toast.select-required": "Select conflicts first.",
"photos.sync.conflicts.total": "Total: {{count}}",
"photos.sync.metadata.database": "Metadata · database",
"photos.sync.metadata.etag": "ETag",
"photos.sync.metadata.hash": "Metadata hash",
"photos.sync.metadata.none": "None",
"photos.sync.metadata.size": "Size",
"photos.sync.metadata.storage": "Metadata · storage",
"photos.sync.metadata.unknown": "Unknown",
"photos.sync.metadata.updated-at": "Updated",
"photos.sync.progress.heading.error": "Sync failed",
"photos.sync.progress.heading.preview": "Running preview sync",
"photos.sync.progress.heading.running": "Running sync",
"photos.sync.progress.logs.detail.error": "Error {{value}}",
"photos.sync.progress.logs.detail.live-photo": "Includes Live Photo",
"photos.sync.progress.logs.detail.live-photo-absent": "No Live Photo",
"photos.sync.progress.logs.detail.manifest": "Includes previous manifest",
"photos.sync.progress.logs.detail.manifest-absent": "No previous manifest",
"photos.sync.progress.logs.detail.result": "Result {{value}}",
"photos.sync.progress.logs.level.error": "Error",
"photos.sync.progress.logs.level.info": "Info",
"photos.sync.progress.logs.level.success": "Success",
"photos.sync.progress.logs.level.warn": "Warning",
"photos.sync.progress.logs.recent": "Latest {{count}} entries",
"photos.sync.progress.logs.title": "Sync logs",
"photos.sync.progress.recent.no-further": "No further actions required",
"photos.sync.progress.recent.progress": "Progress: {{processed}} / {{total}}",
"photos.sync.progress.recent.title": "Recent action",
"photos.sync.progress.stage-status.completed": "Completed",
"photos.sync.progress.stage-status.pending": "Pending",
"photos.sync.progress.stage-status.running": "Running",
"photos.sync.progress.stages.conflicts.description": "Detect differences between storage metadata and database records.",
"photos.sync.progress.stages.conflicts.label": "Verify metadata",
"photos.sync.progress.stages.missing.description": "Sync new objects from storage into the database.",
"photos.sync.progress.stages.missing.label": "Import new photos",
"photos.sync.progress.stages.orphan.description": "Mark database entries whose storage objects are missing.",
"photos.sync.progress.stages.orphan.label": "Identify orphan records",
"photos.sync.progress.stages.progress": "{{processed}} / {{total}}",
"photos.sync.progress.stages.reconciliation.description": "Update record statuses to match the latest metadata.",
"photos.sync.progress.stages.reconciliation.label": "Reconcile statuses",
"photos.sync.progress.status.error": "Stopped",
"photos.sync.progress.status.running": "In progress",
"photos.sync.progress.subtitle.error": "An error occurred during sync. Review the log for details and retry.",
"photos.sync.progress.subtitle.preview": "Simulating sync operations. Preview mode does not write to the database.",
"photos.sync.progress.subtitle.running": "Reconciling storage with the database. Keep this page open to view live progress.",
"photos.sync.result.actions.applied": "Applied",
"photos.sync.result.actions.collapse": "Hide details",
"photos.sync.result.actions.expand": "View details",
"photos.sync.result.actions.pending": "Not applied",
"photos.sync.result.alerts.open-original-failed": "Unable to open original photo",
"photos.sync.result.duration.less-than-second": "Less than 1 second",
"photos.sync.result.duration.minutes": "{{count}} min",
"photos.sync.result.duration.seconds": "{{count}} sec",
"photos.sync.result.filters.all": "All",
"photos.sync.result.history.completed-at": "Completed {{time}}",
"photos.sync.result.history.duration": "Duration {{duration}}",
"photos.sync.result.history.heading": "Last sync completed",
"photos.sync.result.history.mode.live": "Live mode · Changes applied",
"photos.sync.result.history.mode.preview": "Preview mode · No database writes",
"photos.sync.result.history.operations": "Actions: {{count}}",
"photos.sync.result.info.conflict-type": "Conflict type:",
"photos.sync.result.info.photo-id": "Photo ID:",
"photos.sync.result.info.storage-key": "Storage key:",
"photos.sync.result.manifest.empty": "No manifest data",
"photos.sync.result.operations.count": "Operations: {{count}}",
"photos.sync.result.operations.filter-label": "· Filter:",
"photos.sync.result.status.empty.description": "Configure and activate a storage provider in Settings, then use the sync controls to start processing. Preview runs are safe and do not mutate data.",
"photos.sync.result.status.empty.title": "No sync runs yet",
"photos.sync.result.status.loading.description": "Fetching the latest sync run. Please wait…",
"photos.sync.result.status.loading.title": "Loading sync status",
"photos.sync.result.summary.description.latest": "Latest sync results are shown below.",
"photos.sync.result.summary.description.live": "The last sync ran in live mode and wrote changes to the database.",
"photos.sync.result.summary.description.preview": "Preview mode ran most recently; no database changes were applied.",
"photos.sync.result.summary.heading": "Sync summary",
"photos.sync.result.summary.labels.completed": "Synced",
"photos.sync.result.summary.labels.conflicts": "Conflicts",
"photos.sync.result.summary.labels.database-records": "Database records",
"photos.sync.result.summary.labels.deleted": "Records deleted",
"photos.sync.result.summary.labels.errors": "Errors",
"photos.sync.result.summary.labels.inserted": "Photos inserted",
"photos.sync.result.summary.labels.pending": "Pending",
"photos.sync.result.summary.labels.skipped": "Skipped",
"photos.sync.result.summary.labels.storage-objects": "Storage objects",
"photos.sync.result.summary.labels.updated": "Records updated",
"photos.sync.result.table.empty.filtered": "No actions match the current filter.",
"photos.sync.result.table.empty.none": "Sync finished with no actions to review.",
"photos.sync.result.table.mode.live": "Live mode · Results saved",
"photos.sync.result.table.mode.preview": "Preview mode · No changes applied",
"photos.sync.result.table.title": "Sync action details",
"photos.sync.toasts.conflict-batch-error": "Some conflicts failed to resolve",
"photos.sync.toasts.conflict-batch-success": "{{strategy}} resolved {{count}} conflict(s).",
"photos.sync.toasts.conflict-database": "Database record retained; storage difference ignored.",
"photos.sync.toasts.conflict-error": "Failed to resolve conflict",
"photos.sync.toasts.conflict-error-desc": "Unable to resolve conflict right now. Please try again later.",
"photos.sync.toasts.conflict-resolved": "Conflict resolved",
"photos.sync.toasts.conflict-select": "Select at least one conflict first.",
"photos.sync.toasts.conflict-storage": "Storage version applied to the database.",
"photos.tabs.library": "Library",
"photos.tabs.storage": "Storage",
"photos.tabs.sync": "Sync",
"photos.tabs.usage": "Usage",
"photos.usage.events.description": "Latest billing-relevant actions such as uploads, deletions, and sync jobs.",
"photos.usage.events.empty.description": "Upload photos or run sync to see billing events here.",
"photos.usage.events.empty.title": "No usage yet",
"photos.usage.events.metadata.empty": "—",
"photos.usage.events.metadata.more": "+{{count}} more",
"photos.usage.events.metadata.value-unknown": "N/A",
"photos.usage.events.title": "Recent usage events",
"photos.usage.events.total": "{{count}} event(s)",
"photos.usage.events.unit.byte": "Bytes",
"photos.usage.events.unit.count": "Actions",
"photos.usage.events.unit.label": "Unit: {{unit}}",
"photos.usage.photo-created.description": "Photos added through upload or sync.",
"photos.usage.photo-created.label": "Photo created",
"photos.usage.photo-deleted.description": "Photos removed from the library or storage.",
"photos.usage.photo-deleted.label": "Photo deleted",
"photos.usage.summary.description": "Cumulative totals grouped by event type.",
"photos.usage.summary.refresh": "Refresh",
"photos.usage.summary.title": "Usage overview",
"photos.usage.sync-completed.description": "Summary event when a data sync run finishes.",
"photos.usage.sync-completed.label": "Sync completed",
"plan.badge.current": "Current Plan",
"plan.badge.internal": "Internal Plan",
"plan.checkout.coming-soon": "Coming Soon",
"plan.checkout.loading": "Please wait…",
"plan.checkout.upgrade": "Upgrade Plan",
"plan.error.load-prefix": "Unable to load subscription:",
"plan.error.unknown": "Unknown error",
"plan.page.description": "Review current subscription limits and manage plan upgrades in one place.",
"plan.page.title": "Subscription Plans",
"plan.portal.loading": "Opening…",
"plan.portal.manage": "Manage Subscription",
"plan.quotas.label.libraryItemLimit": "Library capacity",
"plan.quotas.label.maxSyncObjectSizeMb": "Sync object size",
"plan.quotas.label.maxUploadSizeMb": "Upload size",
"plan.quotas.label.monthlyAssetProcessLimit": "Monthly processed photos",
"plan.quotas.unit.megabytes": "{{value}} MB",
"plan.quotas.unit.photos": "{{value}} photos",
"plan.quotas.unlimited": "Unlimited",
"plan.toast.checkout-failure": "Unable to create checkout session. Please try again later.",
"plan.toast.checkout-unavailable": "This plan is not available yet. Please try again soon.",
"plan.toast.missing-checkout-url": "Checkout link is unavailable. Please try again later.",
"plan.toast.missing-portal-account": "Subscription account not found. Please try again later.",
"plan.toast.missing-portal-url": "Portal link is unavailable. Please try again later.",
"plan.toast.portal-failure": "Unable to open subscription portal. Please try again later.",
"plan.upgrade-modal.action.later": "Maybe later",
"plan.upgrade-modal.action.upgrade": "Go to plans",
"plan.upgrade-modal.description": "Uploads and sync need a higher subscription. Upgrade your plan to continue.",
"plan.upgrade-modal.title": "Upgrade required",
"schema-form.secret.helper": "For security, provide a new value only when updating.",
"schema-form.secret.hide": "Hide",
"schema-form.secret.show": "Show",
"schema-form.select.placeholder": "Select an option",
"settings.account.description": "Link third-party accounts and sign in to the dashboard with OAuth.",
"settings.account.title": "Account & Login",
"settings.data.description": "Run database maintenance tasks to keep photo data consistent with object storage.",
"settings.data.title": "Data Management",
"settings.domain.actions.copy": "Copy",
"settings.domain.actions.verify": "Verify",
"settings.domain.banner.pending": "Pending verification for {{domain}}. DNS changes may take a few minutes to propagate.",
"settings.domain.bound-list.empty": "No custom domains yet. Add one on the left to start verification.",
"settings.domain.bound-list.title": "Bound domains",
"settings.domain.description": "Bind your own domain to serve the gallery under a branded URL.",
"settings.domain.dns.cname.helper": "Once TXT passes, point your custom domain to this target.",
"settings.domain.dns.cname.title": "CNAME target (after TXT verified)",
"settings.domain.dns.hint.ttl": "300s or provider default",
"settings.domain.dns.name": "Name / Host",
"settings.domain.dns.ttl": "TTL",
"settings.domain.dns.txt.title": "TXT record (required)",
"settings.domain.dns.type": "Type",
"settings.domain.dns.value": "Value",
"settings.domain.input.cta": "Bind domain",
"settings.domain.input.helper": "Use the root domain or a subdomain. Avoid the platform base domain {{base}} itself.",
"settings.domain.input.label": "Custom domain",
"settings.domain.input.placeholder": "photos.yourdomain.com",
"settings.domain.status.disabled": "Disabled",
"settings.domain.status.pending": "Pending DNS",
"settings.domain.status.verified": "Active",
"settings.domain.steps.cname.desc": "After TXT verification succeeds, point a CNAME to {{base}} so the domain serves your site.",
"settings.domain.steps.cname.title": "Point CNAME to workspace",
"settings.domain.steps.title": "Verification steps",
"settings.domain.steps.txt.desc": "Create a TXT record (preferred at _afilmory-verification.<your-domain>) containing the verification token.",
"settings.domain.steps.txt.title": "Add TXT verification (required)",
"settings.domain.steps.verify.desc": "When the TXT record is live, click Verify to activate the domain.",
"settings.domain.steps.verify.title": "Verify and publish",
"settings.domain.title": "Custom domain",
"settings.domain.toast.delete-failed": "Failed to remove domain",
"settings.domain.toast.delete-success": "Domain removed",
"settings.domain.toast.input-required": "Please enter a domain before binding.",
"settings.domain.toast.request-failed": "Failed to bind domain",
"settings.domain.toast.request-success": "Domain added. Please complete DNS and verify.",
"settings.domain.toast.verify-failed": "Verification failed. Please verify DNS and try again.",
"settings.domain.toast.verify-success": "Domain verified and activated",
"settings.domain.token.helper": "Publish this token in a TXT record (ideally _afilmory-verification.<your-domain>).",
"settings.domain.token.label": "Verification token",
"settings.nav.account": "Account & Login",
"settings.nav.data": "Data Management",
"settings.nav.domain": "Custom Domain",
"settings.nav.site": "Site Settings",
"settings.nav.user": "User Profile",
"settings.site.description": "Configure branding, social links, and map display for the public site.",
"settings.site.title": "Site Settings",
"settings.user.description": "Maintain the public author profile, avatar, and aliases.",
"settings.user.title": "User Profile",
"site.settings.banner.dirty": "{{count}} setting(s) pending save",
"site.settings.banner.fail": "Save failed:",
"site.settings.banner.success": "Settings synced successfully",
"site.settings.banner.synced": "All settings are up to date",
"site.settings.button.save": "Save changes",
"site.settings.button.saving": "Saving…",
"site.settings.error.load-prefix": "Unable to load site settings:",
"site.settings.error.unknown": "Unknown error",
"site.user.blocker.cancel": "Stay on this page",
"site.user.blocker.confirm": "Leave anyway",
"site.user.blocker.description": "You have unsaved edits. Leaving now will discard them. Continue?",
"site.user.blocker.title": "Save changes before leaving",
"site.user.button.save": "Save changes",
"site.user.button.saving": "Saving…",
"site.user.error.loading": "Unable to load user profile",
"site.user.form.avatar.helper": "Supports http(s) URLs or links starting with //. Leave blank to fallback to initials.",
"site.user.form.avatar.label": "Avatar URL",
"site.user.form.avatar.placeholder": "https://cdn.example.com/avatar.png",
"site.user.form.display.helper": "Shown next to the avatar. Leave blank to reuse the author name.",
"site.user.form.display.label": "Display name",
"site.user.form.display.placeholder": "Optional, e.g., innei.photo",
"site.user.form.name.helper": "Displayed publicly and in RSS author/editor fields.",
"site.user.form.name.label": "Author name",
"site.user.form.name.placeholder": "e.g., Innei",
"site.user.form.username.helper": "Used internally to identify the author. Not shown on the site.",
"site.user.form.username.label": "Username (optional)",
"site.user.form.username.placeholder": "e.g., innei",
"site.user.header.badge": "Author profile",
"site.user.header.description": "Used on the site header, RSS feed, and social cards. Keep it aligned with your personal brand.",
"site.user.header.title": "Public author identity",
"site.user.preview.avatar-alt": "Author avatar preview",
"site.user.preview.fallback": "Author",
"site.user.preview.last-updated": "Last updated: {{time}}",
"site.user.preview.never-updated": "Not updated yet",
"site.user.toast.error": "Failed to save profile",
"site.user.toast.error-description": "Please review your input and try again.",
"site.user.toast.success": "Profile updated",
"storage.providers.actions.add": "Add provider",
"storage.providers.actions.cancel": "Cancel",
"storage.providers.actions.create": "Create provider",
"storage.providers.actions.save": "Save changes",
"storage.providers.actions.saving": "Saving…",
"storage.providers.blocker.cancel": "Stay on this page",
"storage.providers.blocker.confirm": "Leave anyway",
"storage.providers.blocker.description": "You have unsaved storage provider changes. Leaving this page will discard them. Continue?",
"storage.providers.blocker.title": "Save storage changes first",
"storage.providers.card.active": "Active",
"storage.providers.card.edit": "Edit",
"storage.providers.card.make-active": "Make active",
"storage.providers.card.make-inactive": "Make inactive",
"storage.providers.card.preview.fallback": "Storage provider",
"storage.providers.card.preview.not-configured": "Not configured",
"storage.providers.card.untitled": "Untitled provider",
"storage.providers.empty.action": "Add provider",
"storage.providers.empty.description": "Add a storage provider so the system can sync and manage remote photos.",
"storage.providers.empty.title": "No storage provider configured",
"storage.providers.error.load": "Unable to load storage settings",
"storage.providers.fields.github.branch.description": "Optional branch to sync.",
"storage.providers.fields.github.branch.helper": "Defaults to master/main. Provide the full branch name if it differs.",
"storage.providers.fields.github.branch.label": "Branch",
"storage.providers.fields.github.branch.placeholder": "main",
"storage.providers.fields.github.custom-domain.description": "CDN or proxy domain used when generating public URLs.",
"storage.providers.fields.github.custom-domain.helper": "Leave blank to keep raw.githubusercontent.com URLs.",
"storage.providers.fields.github.custom-domain.label": "Custom CDN domain",
"storage.providers.fields.github.custom-domain.placeholder": "cdn.jsdelivr.net/gh/owner/repo@branch",
"storage.providers.fields.github.owner.description": "GitHub user or organization name.",
"storage.providers.fields.github.owner.label": "Repository owner",
"storage.providers.fields.github.owner.placeholder": "afilmory",
"storage.providers.fields.github.path.description": "Optional path within the repository to limit syncing.",
"storage.providers.fields.github.path.label": "Repository path",
"storage.providers.fields.github.path.placeholder": "public/photos",
"storage.providers.fields.github.repo.description": "Repository that stores your photos.",
"storage.providers.fields.github.repo.label": "Repository name",
"storage.providers.fields.github.repo.placeholder": "photo-assets",
"storage.providers.fields.github.token.description": "Personal Access Token for private repositories.",
"storage.providers.fields.github.token.label": "Access token",
"storage.providers.fields.github.token.placeholder": "ghp_xxxxxxxxxxxxxxxxxxxx",
"storage.providers.fields.github.use-raw.description": "Use raw.githubusercontent.com when generating public URLs.",
"storage.providers.fields.github.use-raw.helper": "Set to false if you serve files via a custom domain.",
"storage.providers.fields.github.use-raw.label": "Use raw URL",
"storage.providers.fields.github.use-raw.placeholder": "true / false",
"storage.providers.fields.s3.access-key.label": "Access Key ID",
"storage.providers.fields.s3.access-key.placeholder": "AKIAxxxxxxxxxxxx",
"storage.providers.fields.s3.bucket.description": "Name of the S3 bucket that stores your photos.",
"storage.providers.fields.s3.bucket.label": "Bucket name",
"storage.providers.fields.s3.bucket.placeholder": "afilmory-photos",
"storage.providers.fields.s3.custom-domain.description": "Domain used when generating public photo URLs.",
"storage.providers.fields.s3.custom-domain.label": "Custom public domain",
"storage.providers.fields.s3.custom-domain.placeholder": "https://cdn.example.com",
"storage.providers.fields.s3.endpoint.description": "Optional endpoint for S3-compatible services.",
"storage.providers.fields.s3.endpoint.helper": "Leave empty for AWS S3. Required for MinIO or other vendors.",
"storage.providers.fields.s3.endpoint.label": "Custom endpoint",
"storage.providers.fields.s3.endpoint.placeholder": "https://s3.example.com",
"storage.providers.fields.s3.exclude-regex.description": "Optional. Skip files that match this regular expression.",
"storage.providers.fields.s3.exclude-regex.helper": "Use JavaScript-compatible regular expressions.",
"storage.providers.fields.s3.exclude-regex.label": "Exclude pattern (regex)",
"storage.providers.fields.s3.exclude-regex.placeholder": "\\\\.(tmp|bak)$",
"storage.providers.fields.s3.max-files.description": "Optional limit for how many files to scan per run.",
"storage.providers.fields.s3.max-files.label": "Max files",
"storage.providers.fields.s3.max-files.placeholder": "1000",
"storage.providers.fields.s3.prefix.description": "Optional. Limit scanning to objects under this prefix.",
"storage.providers.fields.s3.prefix.label": "Path prefix",
"storage.providers.fields.s3.prefix.placeholder": "photos/",
"storage.providers.fields.s3.region.description": "S3 region code, e.g. ap-southeast-1.",
"storage.providers.fields.s3.region.label": "Region",
"storage.providers.fields.s3.region.placeholder": "ap-southeast-1",
"storage.providers.fields.s3.secret-key.label": "Secret Access Key",
"storage.providers.fields.s3.secret-key.placeholder": "************",
"storage.providers.modal.create.description": "Configure a new storage backend for your photos.",
"storage.providers.modal.create.title": "Add storage provider",
"storage.providers.modal.edit.description": "Update provider credentials and options.",
"storage.providers.modal.edit.title": "Edit provider",
"storage.providers.modal.fields.name.label": "Display name",
"storage.providers.modal.fields.name.placeholder": "e.g., Production S3",
"storage.providers.modal.fields.required": "Required",
"storage.providers.modal.fields.type.label": "Provider type",
"storage.providers.modal.fields.type.placeholder": "Select a provider",
"storage.providers.modal.sections.basic": "Basic information",
"storage.providers.modal.sections.connection": "Connection configuration",
"storage.providers.prompt.sync.cancel": "Maybe later",
"storage.providers.prompt.sync.confirm": "Start syncing",
"storage.providers.prompt.sync.description": "Storage provider configuration is saved. Go to Data Sync now to scan storage and update the database?",
"storage.providers.prompt.sync.title": "Sync photos now?",
"storage.providers.secure-access.description": "Serve downloads via short-lived, presigned URLs so you can revoke access and trace requests. Disable to fall back to direct bucket URLs (less secure).",
"storage.providers.secure-access.helper": "Recommended for managed storage or when you need detailed access logs. Requires S3 credentials that allow presigned downloads.",
"storage.providers.secure-access.managed-note": "Managed tenants follow the platform-wide policy controlled by the super admin.",
"storage.providers.secure-access.title": "Secure Access Proxy",
"storage.providers.security.description": "Sensitive credentials (keys, tokens, etc.) are encrypted with {{algorithm}} to protect your data.",
"storage.providers.security.helper": "{{algorithm}} provides authenticated encryption to keep data confidential and tamper-proof.",
"storage.providers.security.title": "Storage Security",
"storage.providers.status.dirty": "{{total}} provider(s) pending save",
"storage.providers.status.error": "Save failed: {{reason}}",
"storage.providers.status.saved": "✓ Storage configuration saved",
"storage.providers.status.summary": "{{total}} storage provider(s) • {{active}} active",
"storage.providers.types.b2": "Backblaze B2 cloud storage",
"storage.providers.types.cos": "Tencent Cloud COS",
"storage.providers.types.eagle": "Eagle library",
"storage.providers.types.github": "GitHub repository",
"storage.providers.types.local": "Local storage",
"storage.providers.types.minio": "MinIO",
"storage.providers.types.oss": "Aliyun OSS",
"storage.providers.types.s3": "AWS S3 / compatible object storage",
"superadmin.brand": "Afilmory · System Settings",
"superadmin.builder-debug.actions.cancel": "Cancel Debug",
"superadmin.builder-debug.actions.start": "Run Debug",
"superadmin.builder-debug.api.missing-result": "No final debug result was received before the connection ended.",
"superadmin.builder-debug.api.request-failed": "Debug request failed: {{status}} {{statusText}}",
"superadmin.builder-debug.description": "Run single-image builder pipeline verification without touching persistent data.",
"superadmin.builder-debug.input.clear": "Clear",
"superadmin.builder-debug.input.file-meta": "{{size}} · {{type}}",
"superadmin.builder-debug.input.max": "Only one image, up to 25 MB",
"superadmin.builder-debug.input.placeholder": "Click or drag an image here",
"superadmin.builder-debug.input.subtitle": "Select a source image to simulate the builder pipeline.",
"superadmin.builder-debug.input.title": "Debug input",
"superadmin.builder-debug.log.level.error": "ERROR",
"superadmin.builder-debug.log.level.info": "INFO",
"superadmin.builder-debug.log.level.success": "SUCCESS",
"superadmin.builder-debug.log.level.warn": "WARN",
"superadmin.builder-debug.log.message.complete": "Build finished · result {{resultType}}",
"superadmin.builder-debug.log.message.start": "Uploading {{filename}} · preparing builder run",
"superadmin.builder-debug.log.status.complete": "COMPLETE",
"superadmin.builder-debug.log.status.error": "ERROR",
"superadmin.builder-debug.log.status.start": "START",
"superadmin.builder-debug.logs.empty": "No logs yet",
"superadmin.builder-debug.logs.initializing": "Preparing the debug environment…",
"superadmin.builder-debug.logs.source": "Source: Builder + Data Sync Relay",
"superadmin.builder-debug.logs.subtitle": "Latest {{count}} messages",
"superadmin.builder-debug.logs.title": "Realtime logs",
"superadmin.builder-debug.notes.keep-page-open": "Keep this page open while the task runs. Logs stream directly from the same builder config used by Data Sync.",
"superadmin.builder-debug.output.after-run": "Manifest details will appear here after running the debug task.",
"superadmin.builder-debug.output.copy": "Copy manifest",
"superadmin.builder-debug.output.no-manifest": "This run did not produce manifest data.",
"superadmin.builder-debug.output.subtitle": "Review the manifest summary returned by Builder.",
"superadmin.builder-debug.output.title": "Debug output",
"superadmin.builder-debug.recent.file": "File",
"superadmin.builder-debug.recent.size": "Size",
"superadmin.builder-debug.recent.storage-key": "Storage Key",
"superadmin.builder-debug.recent.title": "Last task",
"superadmin.builder-debug.safety.items.no-db": "No photo asset records are written to the database",
"superadmin.builder-debug.safety.items.no-storage": "No debug artifacts are kept in storage",
"superadmin.builder-debug.safety.items.realtime": "Logs stream in real time for troubleshooting",
"superadmin.builder-debug.safety.title": "⚠️ Debug runs in safe mode:",
"superadmin.builder-debug.status.error": "Failed",
"superadmin.builder-debug.status.idle": "Ready",
"superadmin.builder-debug.status.running": "Running",
"superadmin.builder-debug.status.success": "Complete",
"superadmin.builder-debug.summary.cleaned": "Artifacts cleaned",
"superadmin.builder-debug.summary.cleaned-no": "No",
"superadmin.builder-debug.summary.cleaned-yes": "Yes",
"superadmin.builder-debug.summary.result-type": "Result type",
"superadmin.builder-debug.summary.storage-key": "Storage Key",
"superadmin.builder-debug.summary.thumbnail": "Thumbnail URL",
"superadmin.builder-debug.summary.thumbnail-missing": "Not generated",
"superadmin.builder-debug.title": "Builder Debug Console",
"superadmin.builder-debug.toast.cancelled": "Debug cancelled",
"superadmin.builder-debug.toast.copy-failure.description": "Please copy the content manually.",
"superadmin.builder-debug.toast.copy-failure.title": "Copy failed",
"superadmin.builder-debug.toast.copy-success": "Manifest copied to clipboard",
"superadmin.builder-debug.toast.failure-fallback": "Debug failed, please check and retry.",
"superadmin.builder-debug.toast.failure.title": "Debug failed",
"superadmin.builder-debug.toast.manual-cancelled-log": "Debug run stopped by user",
"superadmin.builder-debug.toast.manual-cancelled-message": "Debug session was cancelled manually.",
"superadmin.builder-debug.toast.pick-file": "Select an image before running a debug session.",
"superadmin.builder-debug.toast.success.description": "Builder pipeline completed successfully and cleaned up artifacts.",
"superadmin.builder-debug.toast.success.title": "Debug finished",
"superadmin.builder.title": "Builder Settings",
"superadmin.nav.builder": "Builder",
"superadmin.nav.builder-debug": "Builder Debug",
"superadmin.nav.plans": "Plans",
"superadmin.nav.settings": "System Settings",
"superadmin.nav.tenants": "Tenants",
"superadmin.plans.description": "Manage plan quotas, pricing, and Creem product mappings. Only super admins can edit these settings.",
"superadmin.plans.storage.actions.add": "Add plan",
"superadmin.plans.storage.actions.remove": "Remove",
"superadmin.plans.storage.actions.save": "Save storage plans",
"superadmin.plans.storage.description": "Create managed storage plans without editing JSON. One plan per tenant; capacity stacks with app plan bundled storage.",
"superadmin.plans.storage.empty": "No storage plans yet. Add one to get started.",
"superadmin.plans.storage.error": "Failed to load storage plans: {{reason}}",
"superadmin.plans.storage.fields.active": "Expose this plan",
"superadmin.plans.storage.fields.capacity": "Capacity (GB)",
"superadmin.plans.storage.fields.creem": "Creem product ID",
"superadmin.plans.storage.fields.currency": "Currency",
"superadmin.plans.storage.fields.description": "Description",
"superadmin.plans.storage.fields.id": "Plan ID",
"superadmin.plans.storage.fields.name": "Display name",
"superadmin.plans.storage.fields.placeholder.description": "Who is this plan for? What's included?",
"superadmin.plans.storage.fields.placeholder.name": "Managed B2 • 5GB",
"superadmin.plans.storage.fields.price": "Monthly price",
"superadmin.plans.storage.saved": "Storage plans updated",
"superadmin.plans.storage.title": "Storage plans",
"superadmin.plans.storage.validation.block": "Fix validation errors before saving.",
"superadmin.plans.storage.validation.capacity": "Capacity must be a number in GB.",
"superadmin.plans.storage.validation.id": "Plan ID is required.",
"superadmin.plans.storage.validation.name": "Display name is required.",
"superadmin.plans.storage.validation.price": "Price must be a number.",
"superadmin.plans.tabs.app": "App plans",
"superadmin.plans.tabs.storage": "Storage plans",
"superadmin.plans.title": "Plan Configuration",
"superadmin.settings.button.loading": "Saving…",
"superadmin.settings.button.save": "Save changes",
"superadmin.settings.description": "Control platform-wide registration policies and local sign-in channels. Managed centrally by super admins.",
"superadmin.settings.error.loading": "Unable to load super admin settings: {{reason}}",
"superadmin.settings.managed-storage.actions.edit": "Edit",
"superadmin.settings.managed-storage.actions.save": "Save managed provider",
"superadmin.settings.managed-storage.actions.select": "Set as managed",
"superadmin.settings.managed-storage.actions.selected": "Selected",
"superadmin.settings.managed-storage.current": "Managed",
"superadmin.settings.managed-storage.description": "Configure the storage provider used for built-in managed storage (e.g., B2).",
"superadmin.settings.managed-storage.empty": "No storage providers yet. Add one to use as managed storage.",
"superadmin.settings.managed-storage.error": "Failed to load storage providers: {{reason}}",
"superadmin.settings.managed-storage.secure-access.description": "Force managed tenants to serve downloads through presigned URLs for access control and tracing.",
"superadmin.settings.managed-storage.secure-access.helper": "Disabling this exposes raw object-storage URLs to every managed tenant.",
"superadmin.settings.managed-storage.secure-access.title": "Secure access proxy",
"superadmin.settings.managed-storage.title": "Managed storage provider",
"superadmin.settings.managed-storage.type": "Type: {{type}}",
"superadmin.settings.message.dirty": "You have unsaved changes",
"superadmin.settings.message.error": "Failed to save settings: {{reason}}",
"superadmin.settings.message.idle": "All settings are up to date",
"superadmin.settings.message.saved": "Settings saved successfully",
"superadmin.settings.message.saving": "Saving settings…",
"superadmin.settings.message.unknown-error": "Unknown error",
"superadmin.settings.stats.remaining": "Remaining registration slots",
"superadmin.settings.stats.total-users": "Total users",
"superadmin.settings.stats.unlimited": "Unlimited",
"superadmin.settings.tabs.general": "General",
"superadmin.settings.tabs.managed-storage": "Managed Storage",
"superadmin.settings.title": "System Settings",
"superadmin.tenants.button.ban": "Ban",
"superadmin.tenants.button.delete": "Delete",
"superadmin.tenants.button.processing": "Working…",
"superadmin.tenants.button.unban": "Unban",
"superadmin.tenants.description": "Switch plans for specific tenants or suspend those that violate policies.",
"superadmin.tenants.empty": "There are no tenants to manage right now.",
"superadmin.tenants.error.loading": "Unable to load tenant data: {{reason}}",
"superadmin.tenants.filter.all": "All",
"superadmin.tenants.filter.status": "Status",
"superadmin.tenants.modal.overview.details": "Details",
"superadmin.tenants.modal.overview.photos": "Total Photos",
"superadmin.tenants.modal.photos.empty": "No photos found for this tenant.",
"superadmin.tenants.modal.photos.error": "Failed to load photos.",
"superadmin.tenants.modal.photos.loading": "Loading photos...",
"superadmin.tenants.modal.photos.table.created": "Created",
"superadmin.tenants.modal.photos.table.name": "Name",
"superadmin.tenants.modal.photos.table.preview": "Preview",
"superadmin.tenants.modal.photos.table.size": "Size",
"superadmin.tenants.modal.tab.overview": "Overview",
"superadmin.tenants.modal.tab.photos": "Photos",
"superadmin.tenants.pagination.showing": "Showing {{start}}-{{end}} of {{total}}",
"superadmin.tenants.plan.placeholder": "Select a plan",
"superadmin.tenants.prompt.delete.cancel": "Keep tenant",
"superadmin.tenants.prompt.delete.confirm": "Delete tenant",
"superadmin.tenants.prompt.delete.description": "This will permanently delete {{name}} and all related data. Type the slug to confirm.",
"superadmin.tenants.prompt.delete.mismatch": "The slug does not match. Deletion canceled.",
"superadmin.tenants.prompt.delete.placeholder": "Enter slug: {{slug}}",
"superadmin.tenants.prompt.delete.title": "Delete tenant",
"superadmin.tenants.refresh.button": "Refresh list",
"superadmin.tenants.refresh.loading": "Refreshing…",
"superadmin.tenants.search.placeholder": "Search tenants...",
"superadmin.tenants.status.active": "Active",
"superadmin.tenants.status.banned": "Banned",
"superadmin.tenants.status.inactive": "Inactive",
"superadmin.tenants.status.pending": "Pending",
"superadmin.tenants.status.suspended": "Suspended",
"superadmin.tenants.storage-plan.default": "Default (None)",
"superadmin.tenants.storage-plan.placeholder": "Select storage plan",
"superadmin.tenants.storage.columns.files": "Files",
"superadmin.tenants.storage.columns.plan": "Plan",
"superadmin.tenants.storage.columns.tenant": "Tenant",
"superadmin.tenants.storage.columns.usage": "Usage",
"superadmin.tenants.storage.empty": "No tenants are subscribed to managed storage yet.",
"superadmin.tenants.storage.usage.of": "{{used}} / {{total}}",
"superadmin.tenants.storage.usage.unknown": "Unknown",
"superadmin.tenants.storage.usage.unlimited": "Unlimited",
"superadmin.tenants.table.actions": "Actions",
"superadmin.tenants.table.ban": "Ban",
"superadmin.tenants.table.created": "Created",
"superadmin.tenants.table.plan": "Plan",
"superadmin.tenants.table.status": "Status",
"superadmin.tenants.table.storage-plan": "Storage Plan",
"superadmin.tenants.table.tenant": "Tenant",
"superadmin.tenants.table.usage": "Usage",
"superadmin.tenants.tabs.storage": "Storage tenants",
"superadmin.tenants.tabs.subscriptions": "Subscriptions",
"superadmin.tenants.title": "Tenant Subscription Management",
"superadmin.tenants.toast.ban-error": "Failed to update ban status.",
"superadmin.tenants.toast.ban-success": "Tenant {{name}} has been banned.",
"superadmin.tenants.toast.delete-error": "Failed to delete tenant.",
"superadmin.tenants.toast.delete-success": "Tenant {{name}} has been deleted.",
"superadmin.tenants.toast.plan-error": "Failed to update subscription plan.",
"superadmin.tenants.toast.plan-success": "{{name}} switched to the {{planId}} plan.",
"superadmin.tenants.toast.storage-plan-error": "Failed to update storage plan",
"superadmin.tenants.toast.storage-plan-success": "Storage plan updated for {{name}}",
"superadmin.tenants.toast.unban-success": "Tenant {{name}} is no longer banned.",
"superadmin.tenants.usage.empty": "No usage events recorded yet.",
"welcome.tenant-missing.code": "404",
"welcome.tenant-missing.description": "We could not find a space at this address. It may have been removed or the link is incorrect. Double-check the URL, or register your own space to continue using Afilmory.",
"welcome.tenant-missing.home": "Back to home",
"welcome.tenant-missing.register": "Register now",
"welcome.tenant-missing.request": "Requested host:",
"welcome.tenant-missing.title": "Space Not Found",
"welcome.tenant-restricted.code": "403",
"welcome.tenant-restricted.description": "This hostname is reserved by the system and cannot serve a dashboard or public site. To keep exploring Afilmory, use another hostname or register your own dedicated space.",
"welcome.tenant-restricted.home": "Back to home",
"welcome.tenant-restricted.register": "Create a new space",
"welcome.tenant-restricted.request": "Requested host:",
"welcome.tenant-restricted.title": "Space Reserved",
"welcome.tenant-suspended.code": "403",
"welcome.tenant-suspended.contact": "Contact Support",
"welcome.tenant-suspended.description": "This space has been suspended due to a violation of our terms of service or other administrative action. If you believe this is an error, please contact support.",
"welcome.tenant-suspended.home": "Back to home",
"welcome.tenant-suspended.title": "Space Suspended"
}