import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;

import 'app_localizations_en.dart';
import 'app_localizations_zh.dart';

// ignore_for_file: type=lint

/// Callers can lookup localized strings with an instance of AppL10n
/// returned by `AppL10n.of(context)`.
///
/// Applications need to include `AppL10n.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'generated/app_localizations.dart';
///
/// return MaterialApp(
///   localizationsDelegates: AppL10n.localizationsDelegates,
///   supportedLocales: AppL10n.supportedLocales,
///   home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
///   # Internationalization support.
///   flutter_localizations:
///     sdk: flutter
///   intl: any # Use the pinned version from flutter_localizations
///
///   # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, you’ll need to edit this
/// file.
///
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// project’s Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppL10n.supportedLocales
/// property.
abstract class AppL10n {
  AppL10n(String locale)
    : localeName = intl.Intl.canonicalizedLocale(locale.toString());

  final String localeName;

  static AppL10n of(BuildContext context) {
    return Localizations.of<AppL10n>(context, AppL10n)!;
  }

  static const LocalizationsDelegate<AppL10n> delegate = _AppL10nDelegate();

  /// A list of this localizations delegate along with the default localizations
  /// delegates.
  ///
  /// Returns a list of localizations delegates containing this delegate along with
  /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
  /// and GlobalWidgetsLocalizations.delegate.
  ///
  /// Additional delegates can be added by appending to this list in
  /// MaterialApp. This list does not have to be used at all if a custom list
  /// of delegates is preferred or required.
  static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
      <LocalizationsDelegate<dynamic>>[
        delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ];

  /// A list of this localizations delegate's supported locales.
  static const List<Locale> supportedLocales = <Locale>[
    Locale('en'),
    Locale('zh'),
  ];

  /// No description provided for @appTitle.
  ///
  /// In en, this message translates to:
  /// **'Chanora'**
  String get appTitle;

  /// No description provided for @homeNotProductionReadyBanner.
  ///
  /// In en, this message translates to:
  /// **'Beta build — voice in/out wired; not production ready.'**
  String get homeNotProductionReadyBanner;

  /// No description provided for @fieldServerHost.
  ///
  /// In en, this message translates to:
  /// **'Server address'**
  String get fieldServerHost;

  /// No description provided for @fieldNickname.
  ///
  /// In en, this message translates to:
  /// **'Nickname'**
  String get fieldNickname;

  /// No description provided for @fieldServerPassword.
  ///
  /// In en, this message translates to:
  /// **'Server password'**
  String get fieldServerPassword;

  /// No description provided for @fieldServerPasswordHelp.
  ///
  /// In en, this message translates to:
  /// **'Leave blank if the server does not require one.'**
  String get fieldServerPasswordHelp;

  /// No description provided for @fieldPassword.
  ///
  /// In en, this message translates to:
  /// **'Password'**
  String get fieldPassword;

  /// No description provided for @fieldDisplayName.
  ///
  /// In en, this message translates to:
  /// **'Display name'**
  String get fieldDisplayName;

  /// No description provided for @connectAction.
  ///
  /// In en, this message translates to:
  /// **'Connect'**
  String get connectAction;

  /// No description provided for @disconnectAction.
  ///
  /// In en, this message translates to:
  /// **'Leave server'**
  String get disconnectAction;

  /// No description provided for @disconnectConfirmTitle.
  ///
  /// In en, this message translates to:
  /// **'Leave server?'**
  String get disconnectConfirmTitle;

  /// No description provided for @disconnectConfirmBody.
  ///
  /// In en, this message translates to:
  /// **'You will disconnect from the current server.'**
  String get disconnectConfirmBody;

  /// No description provided for @disconnectConfirmCancel.
  ///
  /// In en, this message translates to:
  /// **'Stay'**
  String get disconnectConfirmCancel;

  /// No description provided for @disconnectConfirmAction.
  ///
  /// In en, this message translates to:
  /// **'Leave'**
  String get disconnectConfirmAction;

  /// No description provided for @refreshAction.
  ///
  /// In en, this message translates to:
  /// **'Refresh'**
  String get refreshAction;

  /// No description provided for @diagnosticsAction.
  ///
  /// In en, this message translates to:
  /// **'Diagnostics'**
  String get diagnosticsAction;

  /// No description provided for @diagnosticsSaveAction.
  ///
  /// In en, this message translates to:
  /// **'Save export'**
  String get diagnosticsSaveAction;

  /// No description provided for @diagnosticsLiveUpdating.
  ///
  /// In en, this message translates to:
  /// **'Live updating'**
  String get diagnosticsLiveUpdating;

  /// No description provided for @shareAction.
  ///
  /// In en, this message translates to:
  /// **'Share'**
  String get shareAction;

  /// No description provided for @diagnosticsSaved.
  ///
  /// In en, this message translates to:
  /// **'Diagnostic export saved to {path}'**
  String diagnosticsSaved(String path);

  /// No description provided for @aboutAction.
  ///
  /// In en, this message translates to:
  /// **'About'**
  String get aboutAction;

  /// No description provided for @aboutVersion.
  ///
  /// In en, this message translates to:
  /// **'Version {version}'**
  String aboutVersion(String version);

  /// No description provided for @aboutAuthor.
  ///
  /// In en, this message translates to:
  /// **'Author: Edison Jwa'**
  String get aboutAuthor;

  /// No description provided for @aboutNonAffiliation.
  ///
  /// In en, this message translates to:
  /// **'Chanora is independent and is not affiliated with, endorsed by, sponsored by, or officially associated with TeamSpeak.'**
  String get aboutNonAffiliation;

  /// No description provided for @aboutLicenseHeading.
  ///
  /// In en, this message translates to:
  /// **'License'**
  String get aboutLicenseHeading;

  /// No description provided for @aboutLicenseBody.
  ///
  /// In en, this message translates to:
  /// **'Chanora is dual-licensed under the Apache License, Version 2.0 or the MIT License, at your option. The full license texts ship as LICENSE-APACHE and LICENSE-MIT at the repository root.'**
  String get aboutLicenseBody;

  /// No description provided for @aboutThirdPartyHeading.
  ///
  /// In en, this message translates to:
  /// **'Third-party software'**
  String get aboutThirdPartyHeading;

  /// No description provided for @aboutThirdPartyBody.
  ///
  /// In en, this message translates to:
  /// **'Chanora is built on tsclientlib, flutter_rust_bridge, platform-native audio backends, rusqlite, and the Flutter framework, among others. See the NOTICE file at the repository root for the current attribution list.'**
  String get aboutThirdPartyBody;

  /// No description provided for @copyAction.
  ///
  /// In en, this message translates to:
  /// **'Copy'**
  String get copyAction;

  /// No description provided for @closeAction.
  ///
  /// In en, this message translates to:
  /// **'Close'**
  String get closeAction;

  /// No description provided for @openAction.
  ///
  /// In en, this message translates to:
  /// **'Open'**
  String get openAction;

  /// No description provided for @cancelAction.
  ///
  /// In en, this message translates to:
  /// **'Cancel'**
  String get cancelAction;

  /// No description provided for @retryAction.
  ///
  /// In en, this message translates to:
  /// **'Retry'**
  String get retryAction;

  /// No description provided for @chatAction.
  ///
  /// In en, this message translates to:
  /// **'Chat'**
  String get chatAction;

  /// No description provided for @chatCloseAction.
  ///
  /// In en, this message translates to:
  /// **'Close chat'**
  String get chatCloseAction;

  /// No description provided for @chatNewPrivateAction.
  ///
  /// In en, this message translates to:
  /// **'New private chat'**
  String get chatNewPrivateAction;

  /// No description provided for @chatSearchClientsHint.
  ///
  /// In en, this message translates to:
  /// **'Search clients...'**
  String get chatSearchClientsHint;

  /// No description provided for @chatDirectMessageAction.
  ///
  /// In en, this message translates to:
  /// **'Private message'**
  String get chatDirectMessageAction;

  /// No description provided for @chatPokeAction.
  ///
  /// In en, this message translates to:
  /// **'Poke'**
  String get chatPokeAction;

  /// No description provided for @clientInfoAction.
  ///
  /// In en, this message translates to:
  /// **'Info'**
  String get clientInfoAction;

  /// No description provided for @startAudioAction.
  ///
  /// In en, this message translates to:
  /// **'Start audio'**
  String get startAudioAction;

  /// No description provided for @pttHoldToTalk.
  ///
  /// In en, this message translates to:
  /// **'Hold to talk'**
  String get pttHoldToTalk;

  /// No description provided for @pttTransmitting.
  ///
  /// In en, this message translates to:
  /// **'Transmitting…'**
  String get pttTransmitting;

  /// No description provided for @pttHoldToTalkSemanticsHint.
  ///
  /// In en, this message translates to:
  /// **'Press and hold to transmit voice; release to stop.'**
  String get pttHoldToTalkSemanticsHint;

  /// No description provided for @pttCapabilityBadge.
  ///
  /// In en, this message translates to:
  /// **'PTT: {level} ({backend})'**
  String pttCapabilityBadge(String level, String backend);

  /// No description provided for @pttCapabilityBoundKey.
  ///
  /// In en, this message translates to:
  /// **'Key: {key}'**
  String pttCapabilityBoundKey(String key);

  /// No description provided for @pttCapabilityExplainTitle.
  ///
  /// In en, this message translates to:
  /// **'Push-to-Talk capability'**
  String get pttCapabilityExplainTitle;

  /// No description provided for @pttCapabilityExplainFocusedHeading.
  ///
  /// In en, this message translates to:
  /// **'Focused PTT'**
  String get pttCapabilityExplainFocusedHeading;

  /// No description provided for @pttCapabilityExplainFocusedBody.
  ///
  /// In en, this message translates to:
  /// **'Chanora is currently using Focused Push-to-Talk: the binding only fires while the Chanora window is focused. This is the universal fallback used on every platform when a global capture path is not available.'**
  String get pttCapabilityExplainFocusedBody;

  /// No description provided for @pttCapabilityExplainGoGlobalWindows.
  ///
  /// In en, this message translates to:
  /// **'On Windows, Global PTT is engaged automatically once you bind a key. No additional permission is required.'**
  String get pttCapabilityExplainGoGlobalWindows;

  /// No description provided for @pttCapabilityExplainGoGlobalMacos.
  ///
  /// In en, this message translates to:
  /// **'On macOS, Global PTT requires Input Monitoring permission. Open System Settings → Privacy & Security → Input Monitoring, allow Chanora, then re-bind the key.'**
  String get pttCapabilityExplainGoGlobalMacos;

  /// No description provided for @pttCapabilityExplainGoGlobalLinux.
  ///
  /// In en, this message translates to:
  /// **'On Linux, Global PTT requires a GNOME-Wayland desktop with the GlobalShortcuts portal. Re-bind the key and accept the desktop\'s shortcut dialog when it appears.'**
  String get pttCapabilityExplainGoGlobalLinux;

  /// No description provided for @pttCapabilityExplainGoGlobalIos.
  ///
  /// In en, this message translates to:
  /// **'On iOS, Apple does not expose global hotkeys to apps. Chanora uses the on-screen Push-to-Talk button and only transmits while the app is in the foreground.'**
  String get pttCapabilityExplainGoGlobalIos;

  /// No description provided for @pttCapabilityExplainGoGlobalGeneric.
  ///
  /// In en, this message translates to:
  /// **'Global PTT is not available in this environment. Focused PTT will keep working while the Chanora window has focus.'**
  String get pttCapabilityExplainGoGlobalGeneric;

  /// No description provided for @pttConfigureAction.
  ///
  /// In en, this message translates to:
  /// **'Configure'**
  String get pttConfigureAction;

  /// No description provided for @pttConfigureTitle.
  ///
  /// In en, this message translates to:
  /// **'Configure Push-to-Talk binding'**
  String get pttConfigureTitle;

  /// No description provided for @pttConfigurePrompt.
  ///
  /// In en, this message translates to:
  /// **'Press the key or mouse side button you want to use for Push-to-Talk.'**
  String get pttConfigurePrompt;

  /// No description provided for @pttConfigureWaiting.
  ///
  /// In en, this message translates to:
  /// **'(waiting for input…)'**
  String get pttConfigureWaiting;

  /// No description provided for @pttConfigureCaptured.
  ///
  /// In en, this message translates to:
  /// **'Captured'**
  String get pttConfigureCaptured;

  /// No description provided for @pttConfigurePrivacyNote.
  ///
  /// In en, this message translates to:
  /// **'Chanora never logs the actual key value. Only the input class (keyboard / mouse-side-button) and a platform-neutral label leave this dialog.'**
  String get pttConfigurePrivacyNote;

  /// No description provided for @pttConfigureSaveAction.
  ///
  /// In en, this message translates to:
  /// **'Save'**
  String get pttConfigureSaveAction;

  /// No description provided for @pttConfigurePortalRedirect.
  ///
  /// In en, this message translates to:
  /// **'Your desktop environment will open its own shortcut dialog. Pick the key you want to use for Push-to-Talk.'**
  String get pttConfigurePortalRedirect;

  /// No description provided for @inputMuteAction.
  ///
  /// In en, this message translates to:
  /// **'Mute mic'**
  String get inputMuteAction;

  /// No description provided for @inputUnmuteAction.
  ///
  /// In en, this message translates to:
  /// **'Unmute mic'**
  String get inputUnmuteAction;

  /// No description provided for @outputMuteAction.
  ///
  /// In en, this message translates to:
  /// **'Mute speaker'**
  String get outputMuteAction;

  /// No description provided for @outputUnmuteAction.
  ///
  /// In en, this message translates to:
  /// **'Unmute speaker'**
  String get outputUnmuteAction;

  /// No description provided for @joinChannelAction.
  ///
  /// In en, this message translates to:
  /// **'Join channel'**
  String get joinChannelAction;

  /// No description provided for @leaveChannelAction.
  ///
  /// In en, this message translates to:
  /// **'Leave channel'**
  String get leaveChannelAction;

  /// No description provided for @channelPasswordTitle.
  ///
  /// In en, this message translates to:
  /// **'Channel password'**
  String get channelPasswordTitle;

  /// No description provided for @bookmarksHeading.
  ///
  /// In en, this message translates to:
  /// **'Bookmarks'**
  String get bookmarksHeading;

  /// No description provided for @bookmarksEmpty.
  ///
  /// In en, this message translates to:
  /// **'No bookmarks yet. Enter a server above and tap \"Save bookmark\".'**
  String get bookmarksEmpty;

  /// No description provided for @bookmarkAddAction.
  ///
  /// In en, this message translates to:
  /// **'Save bookmark'**
  String get bookmarkAddAction;

  /// No description provided for @bookmarkAddTitle.
  ///
  /// In en, this message translates to:
  /// **'Save bookmark'**
  String get bookmarkAddTitle;

  /// No description provided for @bookmarkDeleteAction.
  ///
  /// In en, this message translates to:
  /// **'Delete bookmark'**
  String get bookmarkDeleteAction;

  /// No description provided for @statusIdle.
  ///
  /// In en, this message translates to:
  /// **'Not connected'**
  String get statusIdle;

  /// No description provided for @statusConnecting.
  ///
  /// In en, this message translates to:
  /// **'Connecting…'**
  String get statusConnecting;

  /// No description provided for @statusConnected.
  ///
  /// In en, this message translates to:
  /// **'Connected to {server}'**
  String statusConnected(String server);

  /// No description provided for @statusError.
  ///
  /// In en, this message translates to:
  /// **'Error: {message}'**
  String statusError(String message);

  /// No description provided for @statusReconnecting.
  ///
  /// In en, this message translates to:
  /// **'Reconnecting… attempt {attempt}, in {delay}s'**
  String statusReconnecting(int attempt, int delay);

  /// No description provided for @statusConnectionLost.
  ///
  /// In en, this message translates to:
  /// **'Connection lost: {reason}'**
  String statusConnectionLost(String reason);

  /// No description provided for @audioStatsLine.
  ///
  /// In en, this message translates to:
  /// **'TX {sent} frames • RX {received} frames • Mic {ptt}'**
  String audioStatsLine(int sent, int received, String ptt);

  /// No description provided for @channelsHeading.
  ///
  /// In en, this message translates to:
  /// **'Channels'**
  String get channelsHeading;

  /// No description provided for @clientsHeading.
  ///
  /// In en, this message translates to:
  /// **'Online clients'**
  String get clientsHeading;

  /// No description provided for @serverWelcomeHeading.
  ///
  /// In en, this message translates to:
  /// **'Server welcome message'**
  String get serverWelcomeHeading;

  /// No description provided for @countChannelsAndClients.
  ///
  /// In en, this message translates to:
  /// **'{channels} channels • {clients} online'**
  String countChannelsAndClients(int channels, int clients);

  /// No description provided for @voiceModePtt.
  ///
  /// In en, this message translates to:
  /// **'PTT'**
  String get voiceModePtt;

  /// No description provided for @voiceModeContinuous.
  ///
  /// In en, this message translates to:
  /// **'Continuous'**
  String get voiceModeContinuous;

  /// No description provided for @voiceModeVoiceActivity.
  ///
  /// In en, this message translates to:
  /// **'Voice activity'**
  String get voiceModeVoiceActivity;

  /// No description provided for @voiceModeComingSoon.
  ///
  /// In en, this message translates to:
  /// **'Coming soon'**
  String get voiceModeComingSoon;

  /// No description provided for @voiceModeLabel.
  ///
  /// In en, this message translates to:
  /// **'Transmit mode'**
  String get voiceModeLabel;

  /// No description provided for @voiceReleaseTailLabel.
  ///
  /// In en, this message translates to:
  /// **'Release tail'**
  String get voiceReleaseTailLabel;

  /// No description provided for @voiceReleaseTailHint.
  ///
  /// In en, this message translates to:
  /// **'ms'**
  String get voiceReleaseTailHint;

  /// No description provided for @voiceLeaveAction.
  ///
  /// In en, this message translates to:
  /// **'Leave voice'**
  String get voiceLeaveAction;

  /// No description provided for @voiceHardMuteLabel.
  ///
  /// In en, this message translates to:
  /// **'Mute microphone'**
  String get voiceHardMuteLabel;

  /// No description provided for @voiceOutputMuteLabel.
  ///
  /// In en, this message translates to:
  /// **'Mute speakers'**
  String get voiceOutputMuteLabel;

  /// No description provided for @voiceSettingsTitle.
  ///
  /// In en, this message translates to:
  /// **'Voice settings'**
  String get voiceSettingsTitle;

  /// No description provided for @voiceBindKeyAction.
  ///
  /// In en, this message translates to:
  /// **'Bind PTT key'**
  String get voiceBindKeyAction;

  /// No description provided for @voiceBoundKeyLabel.
  ///
  /// In en, this message translates to:
  /// **'Bound key'**
  String get voiceBoundKeyLabel;

  /// No description provided for @voicePttHoldHint.
  ///
  /// In en, this message translates to:
  /// **'Hold the button'**
  String get voicePttHoldHint;

  /// No description provided for @voiceMicOn.
  ///
  /// In en, this message translates to:
  /// **'on'**
  String get voiceMicOn;

  /// No description provided for @voiceMicOff.
  ///
  /// In en, this message translates to:
  /// **'off'**
  String get voiceMicOff;

  /// No description provided for @voiceSheetTitle.
  ///
  /// In en, this message translates to:
  /// **'Voice'**
  String get voiceSheetTitle;

  /// No description provided for @audioOutputLabel.
  ///
  /// In en, this message translates to:
  /// **'Audio output'**
  String get audioOutputLabel;

  /// No description provided for @audioRouteSpeaker.
  ///
  /// In en, this message translates to:
  /// **'Speaker'**
  String get audioRouteSpeaker;

  /// No description provided for @audioRouteReceiver.
  ///
  /// In en, this message translates to:
  /// **'iPhone receiver'**
  String get audioRouteReceiver;

  /// No description provided for @audioRouteBluetooth.
  ///
  /// In en, this message translates to:
  /// **'Bluetooth'**
  String get audioRouteBluetooth;

  /// No description provided for @audioRouteWiredHeadset.
  ///
  /// In en, this message translates to:
  /// **'Wired headset'**
  String get audioRouteWiredHeadset;

  /// No description provided for @audioRouteCarAudio.
  ///
  /// In en, this message translates to:
  /// **'Car audio'**
  String get audioRouteCarAudio;

  /// No description provided for @audioRouteAirplay.
  ///
  /// In en, this message translates to:
  /// **'AirPlay'**
  String get audioRouteAirplay;

  /// No description provided for @audioRouteUnknown.
  ///
  /// In en, this message translates to:
  /// **'Unknown'**
  String get audioRouteUnknown;

  /// No description provided for @channelJoinAlreadyIn.
  ///
  /// In en, this message translates to:
  /// **'Already in this channel.'**
  String get channelJoinAlreadyIn;

  /// No description provided for @channelJoinFailedPermission.
  ///
  /// In en, this message translates to:
  /// **'Insufficient permission to join this channel.'**
  String get channelJoinFailedPermission;

  /// No description provided for @channelJoinFailedPassword.
  ///
  /// In en, this message translates to:
  /// **'Wrong channel password.'**
  String get channelJoinFailedPassword;

  /// No description provided for @channelJoinFailedFull.
  ///
  /// In en, this message translates to:
  /// **'Channel is full.'**
  String get channelJoinFailedFull;

  /// No description provided for @channelJoinFailedFamilyFull.
  ///
  /// In en, this message translates to:
  /// **'Channel family limit reached.'**
  String get channelJoinFailedFamilyFull;

  /// No description provided for @channelJoinFailedPrivate.
  ///
  /// In en, this message translates to:
  /// **'This channel is private.'**
  String get channelJoinFailedPrivate;

  /// No description provided for @channelJoinFailedTimeout.
  ///
  /// In en, this message translates to:
  /// **'Could not join channel: the server didn\'t respond in time.'**
  String get channelJoinFailedTimeout;

  /// No description provided for @channelJoinFailedGeneric.
  ///
  /// In en, this message translates to:
  /// **'Could not join channel: {message}'**
  String channelJoinFailedGeneric(String message);

  /// No description provided for @networkPermissionTitle.
  ///
  /// In en, this message translates to:
  /// **'Network Permission Required'**
  String get networkPermissionTitle;

  /// No description provided for @networkPermissionBody.
  ///
  /// In en, this message translates to:
  /// **'Chanora needs permission to access the network. On macOS, go to System Settings → Privacy & Security → Local Network and enable Chanora, then try again.'**
  String get networkPermissionBody;

  /// No description provided for @networkPermissionOpenSettings.
  ///
  /// In en, this message translates to:
  /// **'Open System Settings'**
  String get networkPermissionOpenSettings;

  /// No description provided for @microphonePermissionTitle.
  ///
  /// In en, this message translates to:
  /// **'Microphone Permission Required'**
  String get microphonePermissionTitle;

  /// No description provided for @microphonePermissionBody.
  ///
  /// In en, this message translates to:
  /// **'Chanora needs permission to access the microphone. On macOS, go to System Settings → Privacy & Security → Microphone and enable Chanora.'**
  String get microphonePermissionBody;

  /// No description provided for @microphonePermissionRequiredForVoice.
  ///
  /// In en, this message translates to:
  /// **'Microphone permission is required for voice transmission.'**
  String get microphonePermissionRequiredForVoice;

  /// No description provided for @permissionGrantAction.
  ///
  /// In en, this message translates to:
  /// **'Grant'**
  String get permissionGrantAction;

  /// No description provided for @startupPermissionsTitle.
  ///
  /// In en, this message translates to:
  /// **'Permissions'**
  String get startupPermissionsTitle;

  /// No description provided for @startupPermissionsBody.
  ///
  /// In en, this message translates to:
  /// **'Chanora requests microphone, Bluetooth headset, and notification permissions at startup so voice, headset routing, and the foreground session work correctly.'**
  String get startupPermissionsBody;

  /// No description provided for @startupPermissionsNotNow.
  ///
  /// In en, this message translates to:
  /// **'Not now'**
  String get startupPermissionsNotNow;

  /// No description provided for @startupPermissionsAllow.
  ///
  /// In en, this message translates to:
  /// **'Allow'**
  String get startupPermissionsAllow;

  /// No description provided for @audioRouteSystemDefault.
  ///
  /// In en, this message translates to:
  /// **'System default'**
  String get audioRouteSystemDefault;

  /// No description provided for @audioRouteEarpiece.
  ///
  /// In en, this message translates to:
  /// **'Earpiece'**
  String get audioRouteEarpiece;

  /// No description provided for @audioRouteUsbHeadset.
  ///
  /// In en, this message translates to:
  /// **'USB headset'**
  String get audioRouteUsbHeadset;

  /// No description provided for @audioRouteOtherDevice.
  ///
  /// In en, this message translates to:
  /// **'Other device'**
  String get audioRouteOtherDevice;

  /// No description provided for @audioRouteRefreshDevices.
  ///
  /// In en, this message translates to:
  /// **'Refresh audio devices'**
  String get audioRouteRefreshDevices;

  /// No description provided for @audioRouteCannotSelect.
  ///
  /// In en, this message translates to:
  /// **'This output cannot be selected.'**
  String get audioRouteCannotSelect;

  /// No description provided for @audioRouteChangeFailed.
  ///
  /// In en, this message translates to:
  /// **'Could not change audio output.'**
  String get audioRouteChangeFailed;

  /// No description provided for @iosAudioInterrupted.
  ///
  /// In en, this message translates to:
  /// **'Audio interrupted by system (phone call)'**
  String get iosAudioInterrupted;

  /// No description provided for @iosAudioResuming.
  ///
  /// In en, this message translates to:
  /// **'Audio resuming'**
  String get iosAudioResuming;

  /// No description provided for @linkTrustTitle.
  ///
  /// In en, this message translates to:
  /// **'Open external link?'**
  String get linkTrustTitle;

  /// No description provided for @linkTrustBody.
  ///
  /// In en, this message translates to:
  /// **'You are about to open a link to:\n\n{domain}'**
  String linkTrustBody(String domain);

  /// No description provided for @linkTrustRememberDomain.
  ///
  /// In en, this message translates to:
  /// **'Trust all links from this domain'**
  String get linkTrustRememberDomain;

  /// No description provided for @clientInfoFetchingProfile.
  ///
  /// In en, this message translates to:
  /// **'Fetching TeamSpeak profile'**
  String get clientInfoFetchingProfile;

  /// No description provided for @clientInfoLoadingProfile.
  ///
  /// In en, this message translates to:
  /// **'Loading profile...'**
  String get clientInfoLoadingProfile;

  /// No description provided for @clientInfoProfileUnavailable.
  ///
  /// In en, this message translates to:
  /// **'Profile unavailable'**
  String get clientInfoProfileUnavailable;

  /// No description provided for @clientInfoProfileUnavailableBody.
  ///
  /// In en, this message translates to:
  /// **'The server did not return profile details for this client.'**
  String get clientInfoProfileUnavailableBody;

  /// No description provided for @clientInfoIdentitySection.
  ///
  /// In en, this message translates to:
  /// **'Identity'**
  String get clientInfoIdentitySection;

  /// No description provided for @clientInfoMembershipSection.
  ///
  /// In en, this message translates to:
  /// **'Membership'**
  String get clientInfoMembershipSection;

  /// No description provided for @clientInfoConnectionSection.
  ///
  /// In en, this message translates to:
  /// **'Connection'**
  String get clientInfoConnectionSection;

  /// No description provided for @clientInfoHistorySection.
  ///
  /// In en, this message translates to:
  /// **'History'**
  String get clientInfoHistorySection;

  /// No description provided for @clientInfoTransferSection.
  ///
  /// In en, this message translates to:
  /// **'Transfer'**
  String get clientInfoTransferSection;

  /// No description provided for @clientInfoClientId.
  ///
  /// In en, this message translates to:
  /// **'Client ID'**
  String get clientInfoClientId;

  /// No description provided for @clientInfoDatabaseId.
  ///
  /// In en, this message translates to:
  /// **'Database ID'**
  String get clientInfoDatabaseId;

  /// No description provided for @clientInfoUniqueId.
  ///
  /// In en, this message translates to:
  /// **'Unique ID'**
  String get clientInfoUniqueId;

  /// No description provided for @clientInfoDescription.
  ///
  /// In en, this message translates to:
  /// **'Description'**
  String get clientInfoDescription;

  /// No description provided for @clientInfoAvatar.
  ///
  /// In en, this message translates to:
  /// **'Avatar'**
  String get clientInfoAvatar;

  /// No description provided for @clientInfoServerGroups.
  ///
  /// In en, this message translates to:
  /// **'Server groups'**
  String get clientInfoServerGroups;

  /// No description provided for @clientInfoChannelGroup.
  ///
  /// In en, this message translates to:
  /// **'Channel group'**
  String get clientInfoChannelGroup;

  /// No description provided for @clientInfoChannelId.
  ///
  /// In en, this message translates to:
  /// **'Channel ID'**
  String get clientInfoChannelId;

  /// No description provided for @clientInfoOnline.
  ///
  /// In en, this message translates to:
  /// **'Online'**
  String get clientInfoOnline;

  /// No description provided for @clientInfoIdle.
  ///
  /// In en, this message translates to:
  /// **'Idle'**
  String get clientInfoIdle;

  /// No description provided for @clientInfoPing.
  ///
  /// In en, this message translates to:
  /// **'Ping'**
  String get clientInfoPing;

  /// No description provided for @clientInfoAddress.
  ///
  /// In en, this message translates to:
  /// **'Address'**
  String get clientInfoAddress;

  /// No description provided for @clientInfoPacketLossClientToServer.
  ///
  /// In en, this message translates to:
  /// **'Packet loss C->S'**
  String get clientInfoPacketLossClientToServer;

  /// No description provided for @clientInfoPacketLossServerToClient.
  ///
  /// In en, this message translates to:
  /// **'Packet loss S->C'**
  String get clientInfoPacketLossServerToClient;

  /// No description provided for @clientInfoFirstConnected.
  ///
  /// In en, this message translates to:
  /// **'First connected'**
  String get clientInfoFirstConnected;

  /// No description provided for @clientInfoLastConnected.
  ///
  /// In en, this message translates to:
  /// **'Last connected'**
  String get clientInfoLastConnected;

  /// No description provided for @clientInfoConnections.
  ///
  /// In en, this message translates to:
  /// **'Connections'**
  String get clientInfoConnections;

  /// No description provided for @clientInfoDownloadedMonth.
  ///
  /// In en, this message translates to:
  /// **'Downloaded this month'**
  String get clientInfoDownloadedMonth;

  /// No description provided for @clientInfoUploadedMonth.
  ///
  /// In en, this message translates to:
  /// **'Uploaded this month'**
  String get clientInfoUploadedMonth;

  /// No description provided for @clientInfoDownloadedTotal.
  ///
  /// In en, this message translates to:
  /// **'Downloaded total'**
  String get clientInfoDownloadedTotal;

  /// No description provided for @clientInfoUploadedTotal.
  ///
  /// In en, this message translates to:
  /// **'Uploaded total'**
  String get clientInfoUploadedTotal;

  /// No description provided for @clientInfoUnknown.
  ///
  /// In en, this message translates to:
  /// **'Unknown'**
  String get clientInfoUnknown;

  /// No description provided for @clientInfoHidden.
  ///
  /// In en, this message translates to:
  /// **'Hidden'**
  String get clientInfoHidden;

  /// No description provided for @clientInfoNone.
  ///
  /// In en, this message translates to:
  /// **'None'**
  String get clientInfoNone;

  /// No description provided for @pokeSnackBarClearAction.
  ///
  /// In en, this message translates to:
  /// **'Clear'**
  String get pokeSnackBarClearAction;

  /// No description provided for @pokeSnackBarMoreIndicator.
  ///
  /// In en, this message translates to:
  /// **'...'**
  String get pokeSnackBarMoreIndicator;

  /// No description provided for @pokeSnackBarIncomingNoMessage.
  ///
  /// In en, this message translates to:
  /// **'{sender} pokes you'**
  String pokeSnackBarIncomingNoMessage(String sender);

  /// No description provided for @pokeSnackBarIncomingWithMessage.
  ///
  /// In en, this message translates to:
  /// **'{sender} pokes you: {message}'**
  String pokeSnackBarIncomingWithMessage(String sender, String message);

  /// No description provided for @pokeHistorySelfNoMessage.
  ///
  /// In en, this message translates to:
  /// **'<{time}> You poked \"{target}\".'**
  String pokeHistorySelfNoMessage(String time, String target);

  /// No description provided for @pokeHistorySelfWithMessage.
  ///
  /// In en, this message translates to:
  /// **'<{time}> You poked \"{target}\" with message: {message}'**
  String pokeHistorySelfWithMessage(String time, String target, String message);

  /// No description provided for @pokeHistoryIncomingNoMessage.
  ///
  /// In en, this message translates to:
  /// **'<{time}> \"{sender}\" pokes you'**
  String pokeHistoryIncomingNoMessage(String time, String sender);

  /// No description provided for @pokeHistoryIncomingWithMessage.
  ///
  /// In en, this message translates to:
  /// **'<{time}> \"{sender}\" pokes you: {message}'**
  String pokeHistoryIncomingWithMessage(
    String time,
    String sender,
    String message,
  );

  /// No description provided for @permissionDenied.
  ///
  /// In en, this message translates to:
  /// **'Permission Denied'**
  String get permissionDenied;
}

class _AppL10nDelegate extends LocalizationsDelegate<AppL10n> {
  const _AppL10nDelegate();

  @override
  Future<AppL10n> load(Locale locale) {
    return SynchronousFuture<AppL10n>(lookupAppL10n(locale));
  }

  @override
  bool isSupported(Locale locale) =>
      <String>['en', 'zh'].contains(locale.languageCode);

  @override
  bool shouldReload(_AppL10nDelegate old) => false;
}

AppL10n lookupAppL10n(Locale locale) {
  // Lookup logic when only language code is specified.
  switch (locale.languageCode) {
    case 'en':
      return AppL10nEn();
    case 'zh':
      return AppL10nZh();
  }

  throw FlutterError(
    'AppL10n.delegate failed to load unsupported locale "$locale". This is likely '
    'an issue with the localizations generation tool. Please file an issue '
    'on GitHub with a reproducible sample app and the gen-l10n configuration '
    'that was used.',
  );
}
