From 904ec8bac8039cd998721e51710be1c71e2b5bb4 Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Fri, 12 Apr 2024 11:36:50 +0300 Subject: [PATCH 01/15] Component dialog (#18) * create showZetaDialog * finished dialog for DeviceType.mobilePortrait * dialog variant for bigger screens * create widgetbook; add Zeta parameter, also in ZetaButton * useRootNavigator: false --- example/lib/home.dart | 2 + .../lib/pages/components/dialog_example.dart | 93 +++++++ example/widgetbook/main.dart | 2 + .../pages/components/dialog_widgetbook.dart | 94 ++++++++ lib/src/components/buttons/button.dart | 16 +- lib/src/components/dialog/dialog.dart | 227 ++++++++++++++++++ lib/src/theme/tokens.dart | 3 + lib/zeta_flutter.dart | 1 + 8 files changed, 437 insertions(+), 1 deletion(-) create mode 100644 example/lib/pages/components/dialog_example.dart create mode 100644 example/widgetbook/pages/components/dialog_widgetbook.dart create mode 100644 lib/src/components/dialog/dialog.dart diff --git a/example/lib/home.dart b/example/lib/home.dart index 2c96e4fe..a122e837 100644 --- a/example/lib/home.dart +++ b/example/lib/home.dart @@ -10,6 +10,7 @@ import 'package:zeta_example/pages/components/button_example.dart'; import 'package:zeta_example/pages/components/checkbox_example.dart'; import 'package:zeta_example/pages/components/chip_example.dart'; import 'package:zeta_example/pages/components/date_input_example.dart'; +import 'package:zeta_example/pages/components/dialog_example.dart'; import 'package:zeta_example/pages/components/dialpad_example.dart'; import 'package:zeta_example/pages/components/dropdown_example.dart'; import 'package:zeta_example/pages/components/list_item_example.dart'; @@ -60,6 +61,7 @@ final List components = [ Component(RadioButtonExample.name, (context) => const RadioButtonExample()), Component(SwitchExample.name, (context) => const SwitchExample()), Component(DateInputExample.name, (context) => const DateInputExample()), + Component(DialogExample.name, (context) => const DialogExample()), ]; final List theme = [ diff --git a/example/lib/pages/components/dialog_example.dart b/example/lib/pages/components/dialog_example.dart new file mode 100644 index 00000000..66d52334 --- /dev/null +++ b/example/lib/pages/components/dialog_example.dart @@ -0,0 +1,93 @@ +import 'package:flutter/material.dart'; +import 'package:zeta_example/widgets.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +class DialogExample extends StatelessWidget { + static const String name = 'Dialog'; + + const DialogExample({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final zeta = Zeta.of(context); + return ExampleScaffold( + name: 'Dialog', + child: Center( + child: Column( + children: [ + TextButton( + onPressed: () => showZetaDialog( + context, + useRootNavigator: false, + title: 'Dialog Title', + icon: Icon( + ZetaIcons.warning_round, + color: zeta.colors.warning, + ), + message: + 'Lorem ipsum dolor sit amet, conse ctetur adipiscing elit, sed do eiusm od tempor incididunt ut labore et do lore magna aliqua.', + primaryButtonLabel: 'Confirm', + ), + child: Text('Show dialog with one button'), + ), + TextButton( + onPressed: () => showZetaDialog( + context, + useRootNavigator: false, + title: 'Dialog Title', + icon: Icon( + ZetaIcons.warning_round, + color: zeta.colors.warning, + ), + message: + 'Lorem ipsum dolor sit amet, conse ctetur adipiscing elit, sed do eiusm od tempor incididunt ut labore et do lore magna aliqua.', + primaryButtonLabel: 'Confirm', + secondaryButtonLabel: 'Cancel', + ), + child: Text('Show dialog with two buttons'), + ), + TextButton( + onPressed: () => showZetaDialog( + context, + useRootNavigator: false, + title: 'Dialog Title', + icon: Icon( + ZetaIcons.warning_round, + color: zeta.colors.warning, + ), + message: + 'Lorem ipsum dolor sit amet, conse ctetur adipiscing elit, sed do eiusm od tempor incididunt ut labore et do lore magna aliqua.', + primaryButtonLabel: 'Confirm', + secondaryButtonLabel: 'Cancel', + tertiaryButtonLabel: 'Learn more', + onTertiaryButtonPressed: () {}, + ), + child: Text('Show dialog with three buttons'), + ), + TextButton( + onPressed: () => showZetaDialog( + context, + useRootNavigator: false, + title: 'Dialog Title', + icon: Icon( + ZetaIcons.warning_round, + color: zeta.colors.warning, + ), + message: + 'Lorem ipsum dolor sit amet, conse ctetur adipiscing elit, sed do eiusm od tempor incididunt ut labore et do lore magna aliqua.', + headerAlignment: ZetaDialogHeaderAlignment.left, + primaryButtonLabel: 'Confirm', + secondaryButtonLabel: 'Cancel', + rounded: false, + ), + child: Text( + 'Show dialog with header to the left\nand sharp buttons', + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ); + } +} diff --git a/example/widgetbook/main.dart b/example/widgetbook/main.dart index 96a46c7f..0720feb4 100644 --- a/example/widgetbook/main.dart +++ b/example/widgetbook/main.dart @@ -14,6 +14,7 @@ import 'pages/components/checkbox_widgetbook.dart'; import 'pages/components/chip_widgetbook.dart'; import 'pages/components/date_input_widgetbook.dart'; import 'pages/components/dial_pad_widgetbook.dart'; +import 'pages/components/dialog_widgetbook.dart'; import 'pages/components/dropdown_widgetbook.dart'; import 'pages/components/in_page_banner_widgetbook.dart'; import 'pages/components/list_item_widgetbook.dart'; @@ -108,6 +109,7 @@ class HotReload extends StatelessWidget { builder: (context) => stepperUseCase(context), ), WidgetbookUseCase(name: 'Tabs', builder: (context) => tabsUseCase(context)), + WidgetbookUseCase(name: 'Dialog', builder: (context) => dialogUseCase(context)), ]..sort((a, b) => a.name.compareTo(b.name)), ), WidgetbookCategory( diff --git a/example/widgetbook/pages/components/dialog_widgetbook.dart b/example/widgetbook/pages/components/dialog_widgetbook.dart new file mode 100644 index 00000000..e7445e7d --- /dev/null +++ b/example/widgetbook/pages/components/dialog_widgetbook.dart @@ -0,0 +1,94 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +import '../../test/test_components.dart'; + +Widget dialogUseCase(BuildContext context) { + final zeta = Zeta.of(context); + final title = context.knobs.string( + label: 'Dialog title', + initialValue: 'Dialog Title', + ); + final message = context.knobs.string( + label: 'Dialog message', + initialValue: + 'Lorem ipsum dolor sit amet, conse ctetur adipiscing elit, sed do eiusm od tempor incididunt ut labore et do lore magna aliqua.', + ); + final rounded = context.knobs.boolean(label: 'Rounded', initialValue: true); + final barrierDismissible = context.knobs.boolean(label: 'Barrier dismissible', initialValue: true); + final headerAlignment = context.knobs.list( + label: 'Header alignment', + options: ZetaDialogHeaderAlignment.values, + labelBuilder: (value) => value.name, + ); + return WidgetbookTestWidget( + widget: Padding( + padding: const EdgeInsets.all(ZetaSpacing.x5), + child: Center( + child: Column( + children: [ + TextButton( + onPressed: () => showZetaDialog( + context, + useRootNavigator: false, + zeta: zeta, + rounded: rounded, + barrierDismissible: barrierDismissible, + headerAlignment: headerAlignment, + title: title, + icon: Icon( + ZetaIcons.warning_round, + color: zeta.colors.warning, + ), + message: message, + primaryButtonLabel: 'Confirm', + ), + child: Text('Show dialog with one button'), + ), + TextButton( + onPressed: () => showZetaDialog( + context, + useRootNavigator: false, + zeta: zeta, + rounded: rounded, + barrierDismissible: barrierDismissible, + headerAlignment: headerAlignment, + title: title, + icon: Icon( + ZetaIcons.warning_round, + color: zeta.colors.warning, + ), + message: message, + primaryButtonLabel: 'Confirm', + secondaryButtonLabel: 'Cancel', + ), + child: Text('Show dialog with two buttons'), + ), + TextButton( + onPressed: () => showZetaDialog( + context, + useRootNavigator: false, + zeta: zeta, + rounded: rounded, + barrierDismissible: barrierDismissible, + headerAlignment: headerAlignment, + title: title, + icon: Icon( + ZetaIcons.warning_round, + color: zeta.colors.warning, + ), + message: message, + primaryButtonLabel: 'Confirm', + secondaryButtonLabel: 'Cancel', + tertiaryButtonLabel: 'Learn more', + onTertiaryButtonPressed: () {}, + ), + child: Text('Show dialog with three buttons'), + ), + ], + ), + ), + ), + ); +} diff --git a/lib/src/components/buttons/button.dart b/lib/src/components/buttons/button.dart index c6c61700..be2087cb 100644 --- a/lib/src/components/buttons/button.dart +++ b/lib/src/components/buttons/button.dart @@ -12,6 +12,7 @@ class ZetaButton extends StatelessWidget { this.type = ZetaButtonType.primary, this.size = ZetaWidgetSize.medium, this.borderType = ZetaWidgetBorder.rounded, + this.zeta, super.key, }); @@ -21,6 +22,7 @@ class ZetaButton extends StatelessWidget { this.onPressed, this.size = ZetaWidgetSize.medium, this.borderType = ZetaWidgetBorder.rounded, + this.zeta, super.key, }) : type = ZetaButtonType.primary; @@ -30,6 +32,7 @@ class ZetaButton extends StatelessWidget { this.onPressed, this.size = ZetaWidgetSize.medium, this.borderType = ZetaWidgetBorder.rounded, + this.zeta, super.key, }) : type = ZetaButtonType.secondary; @@ -39,6 +42,7 @@ class ZetaButton extends StatelessWidget { this.onPressed, this.size = ZetaWidgetSize.medium, this.borderType = ZetaWidgetBorder.rounded, + this.zeta, super.key, }) : type = ZetaButtonType.positive; @@ -48,6 +52,7 @@ class ZetaButton extends StatelessWidget { this.onPressed, this.size = ZetaWidgetSize.medium, this.borderType = ZetaWidgetBorder.rounded, + this.zeta, super.key, }) : type = ZetaButtonType.negative; @@ -57,6 +62,7 @@ class ZetaButton extends StatelessWidget { this.onPressed, this.size = ZetaWidgetSize.medium, this.borderType = ZetaWidgetBorder.rounded, + this.zeta, super.key, }) : type = ZetaButtonType.outline; @@ -66,6 +72,7 @@ class ZetaButton extends StatelessWidget { this.onPressed, this.size = ZetaWidgetSize.medium, this.borderType = ZetaWidgetBorder.rounded, + this.zeta, super.key, }) : type = ZetaButtonType.outlineSubtle; @@ -75,6 +82,7 @@ class ZetaButton extends StatelessWidget { this.onPressed, this.size = ZetaWidgetSize.medium, this.borderType = ZetaWidgetBorder.rounded, + this.zeta, super.key, }) : type = ZetaButtonType.text; @@ -94,6 +102,10 @@ class ZetaButton extends StatelessWidget { /// Size of the button. Defaults to large. final ZetaWidgetSize size; + /// Sometimes we need to pass Zeta from outside, + /// like for example from [showZetaDialog] + final Zeta? zeta; + /// Creates a clone. ZetaButton copyWith({ String? label, @@ -109,13 +121,15 @@ class ZetaButton extends StatelessWidget { type: type ?? this.type, size: size ?? this.size, borderType: borderType ?? this.borderType, + zeta: zeta, key: key ?? this.key, ); } @override Widget build(BuildContext context) { - final colors = Zeta.of(context).colors; + final zeta = this.zeta ?? Zeta.of(context); + final colors = zeta.colors; return ConstrainedBox( constraints: BoxConstraints(minHeight: _minConstraints, minWidth: _minConstraints), child: FilledButton( diff --git a/lib/src/components/dialog/dialog.dart b/lib/src/components/dialog/dialog.dart new file mode 100644 index 00000000..22068383 --- /dev/null +++ b/lib/src/components/dialog/dialog.dart @@ -0,0 +1,227 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import '../../../zeta_flutter.dart'; + +/// [ZetaDialogHeaderAlignment] +enum ZetaDialogHeaderAlignment { + /// [left] + left, + + /// [center] + center, +} + +/// [showZetaDialog] +Future showZetaDialog( + BuildContext context, { + Zeta? zeta, + ZetaDialogHeaderAlignment headerAlignment = ZetaDialogHeaderAlignment.center, + Widget? icon, + String? title, + required String message, + String? primaryButtonLabel, + VoidCallback? onPrimaryButtonPressed, + String? secondaryButtonLabel, + VoidCallback? onSecondaryButtonPressed, + String? tertiaryButtonLabel, + VoidCallback? onTertiaryButtonPressed, + bool rounded = true, + bool barrierDismissible = true, + bool useRootNavigator = true, +}) => + showDialog( + context: context, + barrierDismissible: barrierDismissible, + useRootNavigator: useRootNavigator, + builder: (_) => _ZetaDialog( + zeta: zeta, + headerAlignment: headerAlignment, + icon: icon, + title: title, + message: message, + primaryButtonLabel: primaryButtonLabel, + onPrimaryButtonPressed: onPrimaryButtonPressed, + secondaryButtonLabel: secondaryButtonLabel, + onSecondaryButtonPressed: onSecondaryButtonPressed, + tertiaryButtonLabel: tertiaryButtonLabel, + onTertiaryButtonPressed: onTertiaryButtonPressed, + rounded: rounded, + ), + ); + +class _ZetaDialog extends StatelessWidget { + const _ZetaDialog({ + this.headerAlignment = ZetaDialogHeaderAlignment.center, + this.icon, + this.title, + required this.message, + this.primaryButtonLabel, + this.onPrimaryButtonPressed, + this.secondaryButtonLabel, + this.onSecondaryButtonPressed, + this.tertiaryButtonLabel, + this.onTertiaryButtonPressed, + this.rounded = true, + this.zeta, + }); + + final ZetaDialogHeaderAlignment headerAlignment; + final Widget? icon; + final String? title; + final String message; + final String? primaryButtonLabel; + final VoidCallback? onPrimaryButtonPressed; + final String? secondaryButtonLabel; + final VoidCallback? onSecondaryButtonPressed; + final String? tertiaryButtonLabel; + final VoidCallback? onTertiaryButtonPressed; + final bool rounded; + final Zeta? zeta; + + @override + Widget build(BuildContext context) { + final zeta = this.zeta ?? Zeta.of(context); + final primaryButton = primaryButtonLabel == null + ? null + : ZetaButton( + zeta: zeta, + label: primaryButtonLabel!, + onPressed: onPrimaryButtonPressed ?? () => Navigator.of(context).pop(true), + borderType: rounded ? ZetaWidgetBorder.rounded : ZetaWidgetBorder.sharp, + ); + final secondaryButton = secondaryButtonLabel == null + ? null + : ZetaButton.outlineSubtle( + zeta: zeta, + label: secondaryButtonLabel!, + onPressed: onSecondaryButtonPressed ?? () => Navigator.of(context).pop(false), + borderType: rounded ? ZetaWidgetBorder.rounded : ZetaWidgetBorder.sharp, + ); + final tertiaryButton = tertiaryButtonLabel == null + ? null + : TextButton( + onPressed: onTertiaryButtonPressed, + child: Text(tertiaryButtonLabel!), + ); + final hasButton = primaryButton != null || secondaryButton != null || tertiaryButton != null; + + return AlertDialog( + surfaceTintColor: zeta.colors.surfacePrimary, + shape: const RoundedRectangleBorder(borderRadius: ZetaRadius.large), + title: icon != null || title != null + ? Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: switch (headerAlignment) { + ZetaDialogHeaderAlignment.left => CrossAxisAlignment.start, + ZetaDialogHeaderAlignment.center => CrossAxisAlignment.center, + }, + children: [ + if (icon != null) + Padding( + padding: const EdgeInsets.only(bottom: ZetaSpacing.s), + child: icon, + ), + if (title != null) + Text( + title!, + textAlign: switch (headerAlignment) { + ZetaDialogHeaderAlignment.left => TextAlign.left, + ZetaDialogHeaderAlignment.center => TextAlign.center, + }, + ), + ], + ) + : null, + titlePadding: context.deviceType == DeviceType.mobilePortrait + ? null + : const EdgeInsets.only( + left: ZetaSpacing.x10, + right: ZetaSpacing.x10, + top: ZetaSpacing.m, + ), + titleTextStyle: zetaTextTheme.headlineSmall?.copyWith( + color: zeta.colors.textDefault, + ), + content: Text(message), + contentPadding: context.deviceType == DeviceType.mobilePortrait + ? null + : const EdgeInsets.only( + left: ZetaSpacing.x10, + right: ZetaSpacing.x10, + top: ZetaSpacing.s, + bottom: ZetaSpacing.m, + ), + contentTextStyle: context.deviceType == DeviceType.mobilePortrait + ? zetaTextTheme.bodySmall?.copyWith(color: zeta.colors.textDefault) + : zetaTextTheme.bodyMedium?.copyWith(color: zeta.colors.textDefault), + actions: [ + if (context.deviceType == DeviceType.mobilePortrait) + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (hasButton) const SizedBox(height: ZetaSpacing.m), + if (tertiaryButton == null) + Row( + children: [ + if (secondaryButton != null) Expanded(child: secondaryButton), + if (primaryButton != null && secondaryButton != null) const SizedBox(width: ZetaSpacing.b), + if (primaryButton != null) Expanded(child: primaryButton), + ], + ) + else ...[ + if (primaryButton != null) primaryButton, + if (primaryButton != null && secondaryButton != null) const SizedBox(height: ZetaSpacing.s), + if (secondaryButton != null) secondaryButton, + if (primaryButton != null || secondaryButton != null) const SizedBox(height: ZetaSpacing.xs), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [tertiaryButton], + ), + ], + ], + ) + else + Row( + children: [ + if (tertiaryButton != null) tertiaryButton, + if (primaryButton != null || secondaryButton != null) ...[ + const SizedBox(width: ZetaSpacing.m), + Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + if (secondaryButton != null) secondaryButton, + if (primaryButton != null && secondaryButton != null) const SizedBox(width: ZetaSpacing.b), + if (primaryButton != null) primaryButton, + ], + ), + ), + ], + ], + ), + ], + actionsPadding: context.deviceType == DeviceType.mobilePortrait + ? null + : const EdgeInsets.symmetric( + horizontal: ZetaSpacing.x10, + vertical: ZetaSpacing.m, + ), + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(EnumProperty('headerAlignment', headerAlignment)) + ..add(StringProperty('title', title)) + ..add(StringProperty('message', message)) + ..add(StringProperty('primaryButtonLabel', primaryButtonLabel)) + ..add(ObjectFlagProperty.has('onPrimaryButtonPressed', onPrimaryButtonPressed)) + ..add(StringProperty('secondaryButtonLabel', secondaryButtonLabel)) + ..add(ObjectFlagProperty.has('onSecondaryButtonPressed', onSecondaryButtonPressed)) + ..add(StringProperty('tertiaryButtonLabel', tertiaryButtonLabel)) + ..add(ObjectFlagProperty.has('onTertiaryButtonPressed', onTertiaryButtonPressed)) + ..add(DiagnosticsProperty('rounded', rounded)); + } +} diff --git a/lib/src/theme/tokens.dart b/lib/src/theme/tokens.dart index 5a31e659..caecce51 100644 --- a/lib/src/theme/tokens.dart +++ b/lib/src/theme/tokens.dart @@ -111,6 +111,9 @@ class ZetaRadius { /// Border radius used when rounded parameter is true; 8px radius. static const BorderRadius rounded = BorderRadius.all(Radius.circular(ZetaSpacing.xs)); + /// Large border radius; 16px radius. + static const BorderRadius large = BorderRadius.all(Radius.circular(ZetaSpacing.b)); + /// Wide border radius; 24px radius. static const BorderRadius wide = BorderRadius.all(Radius.circular(ZetaSpacing.m)); diff --git a/lib/zeta_flutter.dart b/lib/zeta_flutter.dart index bca4aef8..0ff913b1 100644 --- a/lib/zeta_flutter.dart +++ b/lib/zeta_flutter.dart @@ -24,6 +24,7 @@ export 'src/components/checkbox/checkbox.dart'; export 'src/components/chips/chip.dart'; export 'src/components/date_input/date_input.dart'; export 'src/components/dial_pad/dial_pad.dart'; +export 'src/components/dialog/dialog.dart'; export 'src/components/dropdown/dropdown.dart'; export 'src/components/list_item/list_item.dart'; export 'src/components/navigation bar/navigation_bar.dart'; From eefcb616044975605ea36e19c9fb9d314c05ee4c Mon Sep 17 00:00:00 2001 From: Luke Date: Fri, 12 Apr 2024 10:15:24 +0100 Subject: [PATCH 02/15] feat(main): AppBar (#19) * feat(main): AppBar * [automated commit] lint format and import sort --------- Co-authored-by: github-actions --- example/lib/main.dart | 194 +++++--- .../lib/pages/components/app_bar_example.dart | 182 ++++++++ example/widgetbook/main.dart | 14 + .../pages/components/app_bar_widgetbook.dart | 164 +++++++ lib/src/components/app_bar/app_bar.dart | 421 ++++++++++++++++++ lib/zeta_flutter.dart | 1 + 6 files changed, 920 insertions(+), 56 deletions(-) create mode 100644 example/lib/pages/components/app_bar_example.dart create mode 100644 example/widgetbook/pages/components/app_bar_widgetbook.dart create mode 100644 lib/src/components/app_bar/app_bar.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index 596eed2e..5078d0e5 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,69 +1,151 @@ import 'package:flutter/material.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:zeta_example/theme_service.dart'; +import 'package:go_router/go_router.dart'; +import 'package:zeta_example/pages/components/accordion_example.dart'; +import 'package:zeta_example/pages/components/app_bar_example.dart'; +import 'package:zeta_example/pages/components/avatar_example.dart'; +import 'package:zeta_example/pages/components/badges_example.dart'; +import 'package:zeta_example/pages/components/banner_example.dart'; +import 'package:zeta_example/pages/components/bottom_sheet_example.dart'; +import 'package:zeta_example/pages/components/breadcrumbs_example.dart'; +import 'package:zeta_example/pages/components/button_example.dart'; +import 'package:zeta_example/pages/components/checkbox_example.dart'; +import 'package:zeta_example/pages/components/chip_example.dart'; +import 'package:zeta_example/pages/components/date_input_example.dart'; +import 'package:zeta_example/pages/components/dialog_example.dart'; +import 'package:zeta_example/pages/components/dialpad_example.dart'; +import 'package:zeta_example/pages/components/dropdown_example.dart'; +import 'package:zeta_example/pages/components/list_item_example.dart'; +import 'package:zeta_example/pages/components/navigation_bar_example.dart'; +import 'package:zeta_example/pages/components/radio_example.dart'; +import 'package:zeta_example/pages/components/stepper_example.dart'; +import 'package:zeta_example/pages/components/switch_example.dart'; +import 'package:zeta_example/pages/components/snackbar_example.dart'; +import 'package:zeta_example/pages/components/tabs_example.dart'; +import 'package:zeta_example/pages/theme/color_example.dart'; +import 'package:zeta_example/pages/components/password_input_example.dart'; +import 'package:zeta_example/pages/components/progress_example.dart'; +import 'package:zeta_example/pages/assets/icons_example.dart'; +import 'package:zeta_example/pages/theme/radius_example.dart'; +import 'package:zeta_example/pages/theme/spacing_example.dart'; +import 'package:zeta_example/pages/theme/typography_example.dart'; +import 'package:zeta_example/widgets.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; -import 'home.dart'; -void main() async { - WidgetsFlutterBinding.ensureInitialized(); +class Component { + final String name; + final WidgetBuilder pageBuilder; + final List children; + Component(this.name, this.pageBuilder, [this.children = const []]); +} - final preferences = await SharedPreferences.getInstance(); - final themeService = SharedPrefsThemeService(preferences); - final themePreferences = await themeService.loadTheme(); +final List components = [ + Component(AccordionExample.name, (context) => const AccordionExample()), + Component(AppBarExample.name, (context) => const AppBarExample()), + Component(AvatarExample.name, (context) => const AvatarExample()), + Component(BannerExample.name, (context) => const BannerExample()), + Component(BadgesExample.name, (context) => const BadgesExample()), + Component(BottomSheetExample.name, (context) => const BottomSheetExample()), + Component(BreadCrumbsExample.name, (context) => const BreadCrumbsExample()), + Component(ButtonExample.name, (context) => const ButtonExample()), + Component(CheckBoxExample.name, (context) => const CheckBoxExample()), + Component(ChipExample.name, (context) => const ChipExample()), + Component(ListItemExample.name, (context) => const ListItemExample()), + Component(NavigationBarExample.name, (context) => const NavigationBarExample()), + Component(PasswordInputExample.name, (context) => const PasswordInputExample()), + Component(DropdownExample.name, (context) => const DropdownExample()), + Component(ProgressExample.name, (context) => const ProgressExample()), + Component(SnackBarExample.name, (context) => const SnackBarExample()), + Component(StepperExample.name, (context) => const StepperExample()), + Component(TabsExample.name, (context) => const TabsExample()), + Component(DialPadExample.name, (context) => const DialPadExample()), + Component(RadioButtonExample.name, (context) => const RadioButtonExample()), + Component(SwitchExample.name, (context) => const SwitchExample()), + Component(DateInputExample.name, (context) => const DateInputExample()), + Component(DialogExample.name, (context) => const DialogExample()), +]; - runApp( - ZetaExample( - themeService: themeService, - initialThemeData: themePreferences.$1 ?? ZetaThemeData(), - initialThemeMode: themePreferences.$2 ?? ThemeMode.system, - initialContrast: themePreferences.$3 ?? ZetaContrast.aa, - ), - ); -} +final List theme = [ + Component(ColorExample.name, (context) => const ColorExample()), + Component(TypographyExample.name, (context) => const TypographyExample()), + Component(RadiusExample.name, (context) => const RadiusExample()), + Component(SpacingExample.name, (context) => const SpacingExample()), +]; +final List assets = [ + Component(IconsExample.name, (context) => const IconsExample()), +]; -class ZetaExample extends StatelessWidget { - const ZetaExample({ - super.key, - required this.themeService, - required this.initialContrast, - required this.initialThemeMode, - required this.initialThemeData, - }); +class Home extends StatefulWidget { + const Home({super.key}); + + @override + State createState() => _HomeState(); +} - final ZetaThemeService themeService; - final ZetaContrast initialContrast; - final ThemeMode initialThemeMode; - final ZetaThemeData initialThemeData; +final GoRouter router = GoRouter( + routes: [ + GoRoute( + path: '/', + name: 'Home', + builder: (_, __) => const Home(), + routes: [ + ...[ + ...components, + ...assets, + ...theme, + ].map( + (e) => GoRoute( + path: e.name, + name: e.name, + builder: (_, __) => e.pageBuilder.call(_), + routes: e.children + .map((f) => GoRoute( + path: f.name, + name: f.name, + builder: (_, __) => f.pageBuilder(_), + )) + .toList(), + ), + ), + ], + ), + ], +); +class _HomeState extends State { @override Widget build(BuildContext context) { - return ZetaProvider( - themeService: themeService, - initialContrast: initialContrast, - initialThemeData: initialThemeData, - initialThemeMode: initialThemeMode, - builder: (context, themeData, themeMode) { - final dark = themeData.colorsDark.toScheme(); - final light = themeData.colorsLight.toScheme(); - return MaterialApp.router( - routerConfig: router, - themeMode: themeMode, - theme: ThemeData( - useMaterial3: true, - fontFamily: themeData.fontFamily, - scaffoldBackgroundColor: light.background, - colorScheme: light, - textTheme: zetaTextTheme, - ), - darkTheme: ThemeData( - useMaterial3: true, - fontFamily: themeData.fontFamily, - scaffoldBackgroundColor: dark.background, - colorScheme: dark, - textTheme: zetaTextTheme, - ), - ); - }, + final _components = components..sort((a, b) => a.name.compareTo(b.name)); + final _assets = assets..sort((a, b) => a.name.compareTo(b.name)); + final _theme = theme..sort((a, b) => a.name.compareTo(b.name)); + return ExampleScaffold( + name: 'Zeta', + child: SingleChildScrollView( + child: Column( + children: [ + ExpansionTile( + title: Text('Widgets'), + backgroundColor: Zeta.of(context).colors.warm.shade30, + children: _components + .map((item) => ListTile(title: Text(item.name), onTap: () => context.go('/${item.name}'))) + .toList(), + ), + ExpansionTile( + title: Text('Theme'), + backgroundColor: Zeta.of(context).colors.warm.shade30, + children: _theme + .map((item) => ListTile(title: Text(item.name), onTap: () => context.go('/${item.name}'))) + .toList(), + ), + ExpansionTile( + title: Text('Assets'), + backgroundColor: Zeta.of(context).colors.warm.shade30, + children: _assets + .map((item) => ListTile(title: Text(item.name), onTap: () => context.go('/${item.name}'))) + .toList(), + ), + ], + ), + ), ); } } diff --git a/example/lib/pages/components/app_bar_example.dart b/example/lib/pages/components/app_bar_example.dart new file mode 100644 index 00000000..250bc8a7 --- /dev/null +++ b/example/lib/pages/components/app_bar_example.dart @@ -0,0 +1,182 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:zeta_example/widgets.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +class AppBarExample extends StatefulWidget { + const AppBarExample({super.key}); + + static const String name = 'AppBar'; + + @override + State createState() => _AppBarExampleState(); +} + +class _AppBarExampleState extends State { + late final _searchController = AppBarSearchController(); + + void _showHideSearch() { + _searchController.isEnabled ? _searchController.closeSearch() : _searchController.startSearch(); + } + + @override + Widget build(BuildContext context) { + return ExampleScaffold( + name: AppBarExample.name, + child: SingleChildScrollView( + child: Column( + children: [ + // Default + Padding( + padding: const EdgeInsets.only(top: ZetaSpacing.x4), + child: ZetaAppBar( + leading: IconButton( + onPressed: () {}, + icon: Icon(Icons.menu_rounded), + ), + title: Row( + children: [ + ZetaAvatar(size: ZetaAvatarSize.xs), + Padding( + padding: const EdgeInsets.only(left: ZetaSpacing.s), + child: Text("Title"), + ), + ], + ), + actions: [ + IconButton( + onPressed: () {}, + icon: Icon(Icons.language), + ), + IconButton( + onPressed: () {}, + icon: Icon(Icons.favorite), + ), + IconButton( + onPressed: () {}, + icon: Icon(ZetaIcons.more_vertical_round), + ) + ], + ), + ), + + // Centered + Padding( + padding: const EdgeInsets.only(top: ZetaSpacing.x4), + child: ZetaAppBar( + type: ZetaAppBarType.centeredTitle, + leading: IconButton( + onPressed: () {}, + icon: Icon(Icons.menu_rounded), + ), + title: Text("Title"), + actions: [ + IconButton( + onPressed: () {}, + icon: Icon(Icons.account_circle), + ), + ], + ), + ), + + // Contextual + Padding( + padding: const EdgeInsets.only(top: ZetaSpacing.x4), + child: ZetaAppBar( + leading: IconButton( + onPressed: () {}, + icon: Icon(ZetaIcons.close_round), + ), + title: Text("2 items"), + actions: [ + IconButton( + onPressed: () {}, + icon: Icon(ZetaIcons.edit_round), + ), + IconButton( + onPressed: () {}, + icon: Icon(ZetaIcons.share_round), + ), + IconButton( + onPressed: () {}, + icon: Icon(ZetaIcons.delete_round), + ), + IconButton( + onPressed: () {}, + icon: Icon(ZetaIcons.more_vertical_round), + ), + ], + ), + ), + + // Search + Padding( + padding: const EdgeInsets.only(top: ZetaSpacing.x4), + child: Column( + children: [ + ZetaAppBar( + type: ZetaAppBarType.centeredTitle, + leading: BackButton(), + title: Text("Title"), + actions: [ + IconButton( + onPressed: _showHideSearch, + icon: Icon(ZetaIcons.search_round), + ) + ], + searchController: _searchController, + onSearch: (text) => debugPrint('search text: $text'), + onSearchMicrophoneIconPressed: () async { + var sampleTexts = [ + 'This is a sample text', + 'Another sample', + 'Speech recognition text', + 'Example' + ]; + + var generatedText = sampleTexts[Random().nextInt(sampleTexts.length)]; + + _searchController.text = generatedText; + }, + ), + ZetaButton.primary( + label: "Show/Hide Search", + onPressed: _showHideSearch, + ) + ], + ), + ), + + // Extended + Padding( + padding: const EdgeInsets.only(top: ZetaSpacing.x4), + child: ZetaAppBar( + type: ZetaAppBarType.extendedTitle, + leading: IconButton( + onPressed: () {}, + icon: Icon(Icons.menu), + ), + title: Text("Large title"), + actions: [ + IconButton( + onPressed: () {}, + icon: Icon(Icons.language), + ), + IconButton( + onPressed: () {}, + icon: Icon(Icons.favorite), + ), + IconButton( + onPressed: () {}, + icon: Icon(ZetaIcons.more_vertical_round), + ) + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/example/widgetbook/main.dart b/example/widgetbook/main.dart index 0720feb4..26299242 100644 --- a/example/widgetbook/main.dart +++ b/example/widgetbook/main.dart @@ -4,6 +4,7 @@ import 'package:zeta_flutter/zeta_flutter.dart'; import 'pages/assets/icon_widgetbook.dart'; import 'pages/components/accordion_widgetbook.dart'; +import 'pages/components/app_bar_widgetbook.dart'; import 'pages/components/avatar_widgetbook.dart'; import 'pages/components/badges_widgetbook.dart'; import 'pages/components/banner_widgetbook.dart'; @@ -47,6 +48,19 @@ class HotReload extends StatelessWidget { name: 'Components', isInitiallyExpanded: false, children: [ + WidgetbookComponent( + name: 'App Bar', + useCases: [ + WidgetbookUseCase( + name: 'Default', + builder: (context) => defaultAppBarUseCase(context), + ), + WidgetbookUseCase( + name: 'Search', + builder: (context) => searchAppBarUseCase(context), + ), + ], + ), WidgetbookComponent( name: 'Badge', useCases: [ diff --git a/example/widgetbook/pages/components/app_bar_widgetbook.dart b/example/widgetbook/pages/components/app_bar_widgetbook.dart new file mode 100644 index 00000000..097cdaf1 --- /dev/null +++ b/example/widgetbook/pages/components/app_bar_widgetbook.dart @@ -0,0 +1,164 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +import '../../test/test_components.dart'; + +Widget defaultAppBarUseCase(BuildContext context) { + return WidgetbookTestWidget( + widget: StatefulBuilder( + builder: (context, setState) { + final title = context.knobs.string(label: "Title", initialValue: "Title"); + + final type = context.knobs.list( + label: "Type", + options: [ + ZetaAppBarType.defaultAppBar, + ZetaAppBarType.centeredTitle, + ZetaAppBarType.extendedTitle, + ], + initialOption: ZetaAppBarType.defaultAppBar, + labelBuilder: (type) => type.name, + ); + + final enabledActions = context.knobs.boolean( + label: "Enabled actions", + initialValue: true, + ); + + final leadingIcon = context.knobs.list( + label: "Leading Icon", + options: [ + Icon( + key: Key("Menu"), + Icons.menu_rounded, + ), + Icon( + key: Key("Close"), + ZetaIcons.close_round, + ), + Icon( + key: Key("Arrow back"), + ZetaIcons.arrow_back_round, + ), + ], + initialOption: Icon(Icons.menu_rounded), + labelBuilder: (icon) => icon.key.toString(), + ); + + return ZetaAppBar( + leading: IconButton( + onPressed: () {}, + icon: leadingIcon, + ), + type: type, + title: Text(title), + actions: enabledActions + ? [ + IconButton( + onPressed: () {}, + icon: Icon(Icons.language), + ), + IconButton( + onPressed: () {}, + icon: Icon(Icons.favorite), + ), + IconButton( + onPressed: () {}, + icon: Icon(ZetaIcons.more_vertical_round), + ) + ] + : null, + ); + }, + ), + ); +} + +Widget searchAppBarUseCase(BuildContext context) { + return WidgetbookTestWidget( + widget: _SearchUseCase(), + ); +} + +class _SearchUseCase extends StatefulWidget { + const _SearchUseCase(); + + @override + State<_SearchUseCase> createState() => _SearchUseCaseState(); +} + +class _SearchUseCaseState extends State<_SearchUseCase> { + late final searchController = AppBarSearchController(); + + @override + Widget build(BuildContext context) { + final title = context.knobs.string(label: "Title", initialValue: "Title"); + + final type = context.knobs.list( + label: "Type", + options: [ + ZetaAppBarType.defaultAppBar, + ZetaAppBarType.centeredTitle, + ZetaAppBarType.extendedTitle, + ], + initialOption: ZetaAppBarType.defaultAppBar, + labelBuilder: (type) => type.name, + ); + + final leadingIcon = context.knobs.list( + label: "Leading Icon", + options: [ + Icon( + key: Key("Menu"), + Icons.menu_rounded, + ), + Icon( + key: Key("Close"), + ZetaIcons.close_round, + ), + Icon( + key: Key("Arrow back"), + ZetaIcons.arrow_back_round, + ), + ], + initialOption: Icon(Icons.menu_rounded), + labelBuilder: (icon) => icon.key.toString(), + ); + + final enabledSpeechRecognition = context.knobs.boolean( + label: "Enabled speech recognition", + description: + "Randomly generated text. There is no real speech recognition. That is just for testing the functionality", + initialValue: false, + ); + + return ZetaAppBar( + leading: IconButton( + onPressed: () {}, + icon: leadingIcon, + ), + type: type, + title: Text(title), + searchController: searchController, + onSearchMicrophoneIconPressed: enabledSpeechRecognition + ? () { + var sampleTexts = ['This is a sample text', 'Another sample', 'Speech recognition text', 'Example']; + + var generatedText = sampleTexts[Random().nextInt(sampleTexts.length)]; + + searchController.text = generatedText; + } + : null, + actions: [ + IconButton( + onPressed: () { + searchController.isEnabled ? searchController.closeSearch() : searchController.startSearch(); + }, + icon: Icon(ZetaIcons.search_round)), + ], + ); + } +} diff --git a/lib/src/components/app_bar/app_bar.dart b/lib/src/components/app_bar/app_bar.dart new file mode 100644 index 00000000..a0debf79 --- /dev/null +++ b/lib/src/components/app_bar/app_bar.dart @@ -0,0 +1,421 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import '../../../zeta_flutter.dart'; + +/// Zeta app bar. +class ZetaAppBar extends StatefulWidget implements PreferredSizeWidget { + /// Creates a Zeta app bar. + const ZetaAppBar({ + this.actions, + this.automaticallyImplyLeading = true, + this.searchController, + this.leading, + this.title, + this.type = ZetaAppBarType.defaultAppBar, + this.onSearch, + this.searchHintText = 'Search', + this.onSearchMicrophoneIconPressed, + super.key, + }); + + /// Called when text in the search field is submited. + final void Function(String)? onSearch; + + /// A list of Widgets to display in a row after the [title] widget. + final List? actions; + + /// Configures whether the back button to be displayed. + final bool automaticallyImplyLeading; + + /// Widget displayed first in the app bar row. + final Widget? leading; + + /// If omitted the microphone icon won't show up. Called when the icon button is pressed. Normally used for speech recognition/speech to text. + final VoidCallback? onSearchMicrophoneIconPressed; + + /// Used to controll the search textfield and states. + final AppBarSearchController? searchController; + + /// Label used as hint text. + final String searchHintText; + + /// Title of the app bar. Normally a [Text] widget. + final Widget? title; + + /// Defines the styles of the app bar. + final ZetaAppBarType type; + + @override + State createState() => _ZetaAppBarState(); + + @override + Size get preferredSize => const Size.fromHeight(kToolbarHeight); + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add( + ObjectFlagProperty.has('onSearch', onSearch), + ) + ..add( + DiagnosticsProperty( + 'automaticallyImplyLeading', + automaticallyImplyLeading, + ), + ) + ..add( + DiagnosticsProperty( + 'searchController', + searchController, + ), + ) + ..add( + ObjectFlagProperty.has( + 'onSearchMicrophoneIconPressed', + onSearchMicrophoneIconPressed, + ), + ) + ..add(StringProperty('searchHintText', searchHintText)) + ..add(EnumProperty('type', type)); + } +} + +class _ZetaAppBarState extends State { + bool _isSearchEnabled = false; + + @override + void initState() { + widget.searchController?.addListener(_onSearchControllerChanged); + super.initState(); + } + + void _onSearchControllerChanged() { + final controller = widget.searchController; + if (controller == null) return; + + setState(() => _isSearchEnabled = controller.isEnabled); + } + + @override + void dispose() { + widget.searchController?.removeListener(_onSearchControllerChanged); + super.dispose(); + } + + Widget? _getTitle() { + return widget.type != ZetaAppBarType.extendedTitle + ? Padding( + padding: const EdgeInsets.symmetric(horizontal: ZetaSpacing.b), + child: widget.title, + ) + : null; + } + + @override + Widget build(BuildContext context) { + final colors = Zeta.of(context).colors; + + return IconButtonTheme( + data: IconButtonThemeData( + style: IconButton.styleFrom( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: ZetaSpacing.b), + child: AppBar( + elevation: 0, + iconTheme: IconThemeData(color: colors.cool.shade90), + leadingWidth: ZetaSpacing.x10, + leading: widget.leading, + automaticallyImplyLeading: widget.automaticallyImplyLeading, + centerTitle: widget.type == ZetaAppBarType.centeredTitle, + titleSpacing: 0, + titleTextStyle: ZetaTextStyles.bodyLarge.copyWith( + color: colors.textDefault, + ), + title: widget.searchController != null + ? _SearchField( + searchController: widget.searchController, + hintText: widget.searchHintText, + onSearch: widget.onSearch, + type: widget.type, + child: _getTitle(), + ) + : _getTitle(), + actions: _isSearchEnabled + ? [ + IconButtonTheme( + data: IconButtonThemeData( + style: IconButton.styleFrom( + iconSize: ZetaSpacing.x5, + ), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + color: colors.cool.shade50, + onPressed: () => widget.searchController?.clearText(), + icon: const Icon(ZetaIcons.cancel_round), + ), + if (widget.onSearchMicrophoneIconPressed != null) ...[ + SizedBox( + height: ZetaSpacing.m, + child: VerticalDivider( + width: ZetaSpacing.x0_5, + color: colors.cool.shade70, + ), + ), + IconButton( + onPressed: widget.onSearchMicrophoneIconPressed, + icon: const Icon(ZetaIcons.microphone_round), + ), + ], + ], + ), + ), + ] + : widget.actions, + flexibleSpace: widget.type == ZetaAppBarType.extendedTitle + ? Padding( + padding: EdgeInsets.only( + top: widget.preferredSize.height, + left: ZetaSpacing.s, + right: ZetaSpacing.s, + ), + child: DefaultTextStyle( + style: ZetaTextStyles.bodyLarge.copyWith( + color: colors.textDefault, + ), + child: widget.title ?? const SizedBox(), + ), + ) + : null, + ), + ), + ); + } +} + +/// Defines the style of the app bar. +enum ZetaAppBarType { + /// Title positioned on the left side. + defaultAppBar, + + /// Title in the center. + centeredTitle, + + /// Title below the app bar. + extendedTitle, +} + +class _SearchField extends StatefulWidget { + const _SearchField({ + required this.child, + required this.onSearch, + required this.searchController, + required this.hintText, + required this.type, + }); + + final void Function(String value)? onSearch; + final Widget? child; + final String hintText; + final AppBarSearchController? searchController; + final ZetaAppBarType type; + + @override + State<_SearchField> createState() => _SearchFieldState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add( + ObjectFlagProperty.has( + 'onSearch', + onSearch, + ), + ) + ..add(StringProperty('hintText', hintText)) + ..add( + DiagnosticsProperty( + 'searchController', + searchController, + ), + ) + ..add(EnumProperty('type', type)); + } +} + +class _SearchFieldState extends State<_SearchField> with SingleTickerProviderStateMixin { + late final _animationController = AnimationController( + vsync: this, + duration: kThemeAnimationDuration, + ); + + late bool _isSearching = widget.searchController?.isEnabled ?? false; + late final _textFocusNode = FocusNode(); + + @override + void initState() { + _textFocusNode.addListener(_onFocusChanged); + widget.searchController?.addListener(_onSearchControllerChanged); + widget.searchController?.textEditingController ??= TextEditingController(); + + super.initState(); + } + + void _onFocusChanged() { + final text = widget.searchController?.text ?? ''; + final shouldCloseSearch = _isSearching && text.isEmpty && !_textFocusNode.hasFocus; + + if (shouldCloseSearch) _closeSearch(); + } + + void _onSearchControllerChanged() { + final controller = widget.searchController; + if (controller == null) return; + + controller.isEnabled ? _startSearch() : _closeSearch(); + } + + void _setNextSearchState() { + if (!_isSearching) return _startSearch(); + + _closeSearch(); + } + + void _startSearch() { + widget.searchController?.startSearch(); + setState(() => _isSearching = true); + + _animationController.forward(); + FocusScope.of(context).requestFocus(_textFocusNode); + } + + void _closeSearch() { + widget.searchController?.closeSearch(); + setState(() => _isSearching = false); + _animationController.reverse(); + _removeFocus(context); + } + + void _submitSearch() { + widget.onSearch?.call(widget.searchController?.text ?? ''); + widget.searchController?.text = ''; + _closeSearch(); + } + + void _removeFocus(BuildContext context) { + final currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) { + FocusManager.instance.primaryFocus?.unfocus(); + } + } + + @override + void didUpdateWidget(covariant _SearchField oldWidget) { + if (oldWidget.searchController != widget.searchController) { + _setNextSearchState(); + } + + super.didUpdateWidget(oldWidget); + } + + @override + void dispose() { + _animationController.dispose(); + _textFocusNode.dispose(); + widget.searchController?.removeListener(_onSearchControllerChanged); + widget.searchController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final colors = Zeta.of(context).colors; + + return Stack( + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Row( + mainAxisAlignment: + widget.type == ZetaAppBarType.centeredTitle ? MainAxisAlignment.center : MainAxisAlignment.start, + children: [ + widget.child ?? const SizedBox(), + ], + ), + AnimatedBuilder( + animation: _animationController, + builder: (context, child) => Transform.scale( + scaleX: _animationController.value * 1, + alignment: Alignment.centerRight, + origin: Offset.zero, + child: TextField( + controller: widget.searchController?.textEditingController, + focusNode: _textFocusNode, + style: ZetaTextStyles.bodyMedium, + cursorColor: colors.cool.shade90, + decoration: InputDecoration( + iconColor: colors.cool.shade90, + filled: true, + border: InputBorder.none, + hintStyle: ZetaTextStyles.bodyMedium.copyWith( + color: colors.textDisabled, + ), + hintText: widget.hintText, + ), + onEditingComplete: _submitSearch, + textInputAction: TextInputAction.search, + ), + ), + ), + ], + ); + } +} + +/// Controlls the search. +class AppBarSearchController extends ChangeNotifier { + bool _enabled = false; + + /// Controller used for the search field. + TextEditingController? textEditingController; + + /// Whether the search is currently vissible. + bool get isEnabled => _enabled; + + /// The current text in the search field. + String get text => textEditingController?.text ?? ''; + + /// Displayes text in the search field and overrides the existing. + set text(String text) => textEditingController?.text = text; + + /// Displays the search field over the title in the app bar. + void startSearch() { + if (_enabled) return; + + _enabled = true; + notifyListeners(); + } + + /// Hides the search field from the app bar. + void closeSearch() { + if (!_enabled) return; + + _enabled = false; + notifyListeners(); + } + + /// Removes the text from search field. + void clearText() => textEditingController?.clear(); + + @override + void dispose() { + textEditingController?.dispose(); + super.dispose(); + } +} diff --git a/lib/zeta_flutter.dart b/lib/zeta_flutter.dart index 0ff913b1..470ce04e 100644 --- a/lib/zeta_flutter.dart +++ b/lib/zeta_flutter.dart @@ -3,6 +3,7 @@ library zeta_flutter; export 'src/assets/icons.dart'; export 'src/components/accordion/accordion.dart'; +export 'src/components/app_bar/app_bar.dart'; export 'src/components/avatars/avatar.dart'; export 'src/components/badges/badge.dart'; export 'src/components/badges/indicator.dart'; From 6966dd98684aeabc0092575af1cc2d055b08852c Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Fri, 12 Apr 2024 18:48:08 +0300 Subject: [PATCH 03/15] Component dialog (#22) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * create showZetaDialog * finished dialog for DeviceType.mobilePortrait * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * dialog variant for bigger screens * create widgetbook; add Zeta parameter, also in ZetaButton * useRootNavigator: false * add iconKnob in Dialog widgetbook * final iconData = iconKnob --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> --- .../pages/components/dialog_widgetbook.dart | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/example/widgetbook/pages/components/dialog_widgetbook.dart b/example/widgetbook/pages/components/dialog_widgetbook.dart index e7445e7d..d00f4381 100644 --- a/example/widgetbook/pages/components/dialog_widgetbook.dart +++ b/example/widgetbook/pages/components/dialog_widgetbook.dart @@ -3,6 +3,7 @@ import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; import '../../test/test_components.dart'; +import '../../utils/utils.dart'; Widget dialogUseCase(BuildContext context) { final zeta = Zeta.of(context); @@ -16,6 +17,12 @@ Widget dialogUseCase(BuildContext context) { 'Lorem ipsum dolor sit amet, conse ctetur adipiscing elit, sed do eiusm od tempor incididunt ut labore et do lore magna aliqua.', ); final rounded = context.knobs.boolean(label: 'Rounded', initialValue: true); + final iconData = iconKnob( + context, + name: "Icon", + rounded: rounded, + initial: rounded ? Icons.warning_rounded : Icons.warning_sharp, + ); final barrierDismissible = context.knobs.boolean(label: 'Barrier dismissible', initialValue: true); final headerAlignment = context.knobs.list( label: 'Header alignment', @@ -38,7 +45,7 @@ Widget dialogUseCase(BuildContext context) { headerAlignment: headerAlignment, title: title, icon: Icon( - ZetaIcons.warning_round, + iconData, color: zeta.colors.warning, ), message: message, @@ -56,7 +63,7 @@ Widget dialogUseCase(BuildContext context) { headerAlignment: headerAlignment, title: title, icon: Icon( - ZetaIcons.warning_round, + iconData, color: zeta.colors.warning, ), message: message, @@ -75,7 +82,7 @@ Widget dialogUseCase(BuildContext context) { headerAlignment: headerAlignment, title: title, icon: Icon( - ZetaIcons.warning_round, + iconData, color: zeta.colors.warning, ), message: message, From 40c543e4fe6627541b831e0b52e3813e45ef4409 Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Tue, 16 Apr 2024 12:11:29 +0300 Subject: [PATCH 04/15] Component phone input (#21) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * ZetaPhoneInput initial commit * complete ZetaPhoneInput; add flags * create phoneInputUseCase in Widgetbook * refactor phone input to use native alert dialog --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> --- example/lib/home.dart | 2 + .../pages/components/phone_input_example.dart | 80 ++ example/widgetbook/main.dart | 4 +- .../components/phone_input_widgetbook.dart | 30 + lib/src/assets/flags/ad.png | Bin 0 -> 2138 bytes lib/src/assets/flags/ae.png | Bin 0 -> 170 bytes lib/src/assets/flags/af.png | Bin 0 -> 2662 bytes lib/src/assets/flags/ag.png | Bin 0 -> 2002 bytes lib/src/assets/flags/ai.png | Bin 0 -> 1366 bytes lib/src/assets/flags/al.png | Bin 0 -> 1759 bytes lib/src/assets/flags/am.png | Bin 0 -> 122 bytes lib/src/assets/flags/an.png | Bin 0 -> 610 bytes lib/src/assets/flags/ao.png | Bin 0 -> 1389 bytes lib/src/assets/flags/aq.png | Bin 0 -> 6114 bytes lib/src/assets/flags/ar.png | Bin 0 -> 991 bytes lib/src/assets/flags/as.png | Bin 0 -> 2038 bytes lib/src/assets/flags/at.png | Bin 0 -> 133 bytes lib/src/assets/flags/au.png | Bin 0 -> 1153 bytes lib/src/assets/flags/aw.png | Bin 0 -> 658 bytes lib/src/assets/flags/ax.png | Bin 0 -> 279 bytes lib/src/assets/flags/az.png | Bin 0 -> 451 bytes lib/src/assets/flags/ba.png | Bin 0 -> 741 bytes lib/src/assets/flags/bb.png | Bin 0 -> 791 bytes lib/src/assets/flags/bd.png | Bin 0 -> 367 bytes lib/src/assets/flags/be.png | Bin 0 -> 168 bytes lib/src/assets/flags/bf.png | Bin 0 -> 560 bytes lib/src/assets/flags/bg.png | Bin 0 -> 106 bytes lib/src/assets/flags/bh.png | Bin 0 -> 303 bytes lib/src/assets/flags/bi.png | Bin 0 -> 1283 bytes lib/src/assets/flags/bj.png | Bin 0 -> 169 bytes lib/src/assets/flags/bl.png | Bin 0 -> 6398 bytes lib/src/assets/flags/bm.png | Bin 0 -> 2009 bytes lib/src/assets/flags/bn.png | Bin 0 -> 2337 bytes lib/src/assets/flags/bo.png | Bin 0 -> 1412 bytes lib/src/assets/flags/bq.png | Bin 0 -> 159 bytes lib/src/assets/flags/br.png | Bin 0 -> 2009 bytes lib/src/assets/flags/bs.png | Bin 0 -> 553 bytes lib/src/assets/flags/bt.png | Bin 0 -> 4119 bytes lib/src/assets/flags/bv.png | Bin 0 -> 260 bytes lib/src/assets/flags/bw.png | Bin 0 -> 172 bytes lib/src/assets/flags/by.png | Bin 0 -> 1473 bytes lib/src/assets/flags/bz.png | Bin 0 -> 5777 bytes lib/src/assets/flags/ca.png | Bin 0 -> 765 bytes lib/src/assets/flags/cc.png | Bin 0 -> 1371 bytes lib/src/assets/flags/cd.png | Bin 0 -> 796 bytes lib/src/assets/flags/cf.png | Bin 0 -> 554 bytes lib/src/assets/flags/cg.png | Bin 0 -> 354 bytes lib/src/assets/flags/ch.png | Bin 0 -> 172 bytes lib/src/assets/flags/ci.png | Bin 0 -> 165 bytes lib/src/assets/flags/ck.png | Bin 0 -> 1953 bytes lib/src/assets/flags/cl.png | Bin 0 -> 517 bytes lib/src/assets/flags/cm.png | Bin 0 -> 482 bytes lib/src/assets/flags/cn.png | Bin 0 -> 763 bytes lib/src/assets/flags/co.png | Bin 0 -> 158 bytes lib/src/assets/flags/cr.png | Bin 0 -> 109 bytes lib/src/assets/flags/cu.png | Bin 0 -> 793 bytes lib/src/assets/flags/cv.png | Bin 0 -> 1040 bytes lib/src/assets/flags/cw.png | Bin 0 -> 633 bytes lib/src/assets/flags/cx.png | Bin 0 -> 1549 bytes lib/src/assets/flags/cy.png | Bin 0 -> 1628 bytes lib/src/assets/flags/cz.png | Bin 0 -> 394 bytes lib/src/assets/flags/de.png | Bin 0 -> 106 bytes lib/src/assets/flags/dj.png | Bin 0 -> 1154 bytes lib/src/assets/flags/dk.png | Bin 0 -> 200 bytes lib/src/assets/flags/dm.png | Bin 0 -> 1229 bytes lib/src/assets/flags/do.png | Bin 0 -> 700 bytes lib/src/assets/flags/dz.png | Bin 0 -> 891 bytes lib/src/assets/flags/ec.png | Bin 0 -> 2568 bytes lib/src/assets/flags/ee.png | Bin 0 -> 158 bytes lib/src/assets/flags/eg.png | Bin 0 -> 1106 bytes lib/src/assets/flags/eh.png | Bin 0 -> 656 bytes lib/src/assets/flags/er.png | Bin 0 -> 1406 bytes lib/src/assets/flags/es.png | Bin 0 -> 1787 bytes lib/src/assets/flags/et.png | Bin 0 -> 1302 bytes lib/src/assets/flags/eu.png | Bin 0 -> 1441 bytes lib/src/assets/flags/fi.png | Bin 0 -> 186 bytes lib/src/assets/flags/fj.png | Bin 0 -> 1821 bytes lib/src/assets/flags/fk.png | Bin 0 -> 2230 bytes lib/src/assets/flags/fm.png | Bin 0 -> 595 bytes lib/src/assets/flags/fo.png | Bin 0 -> 260 bytes lib/src/assets/flags/fr.png | Bin 0 -> 165 bytes lib/src/assets/flags/ga.png | Bin 0 -> 109 bytes lib/src/assets/flags/gb-eng.png | Bin 0 -> 99 bytes lib/src/assets/flags/gb-nir.png | Bin 0 -> 545 bytes lib/src/assets/flags/gb-sct.png | Bin 0 -> 468 bytes lib/src/assets/flags/gb-wls.png | Bin 0 -> 5774 bytes lib/src/assets/flags/gb.png | Bin 0 -> 545 bytes lib/src/assets/flags/gd.png | Bin 0 -> 1530 bytes lib/src/assets/flags/ge.png | Bin 0 -> 750 bytes lib/src/assets/flags/gf.png | Bin 0 -> 738 bytes lib/src/assets/flags/gg.png | Bin 0 -> 306 bytes lib/src/assets/flags/gh.png | Bin 0 -> 549 bytes lib/src/assets/flags/gi.png | Bin 0 -> 1605 bytes lib/src/assets/flags/gl.png | Bin 0 -> 852 bytes lib/src/assets/flags/gm.png | Bin 0 -> 185 bytes lib/src/assets/flags/gn.png | Bin 0 -> 169 bytes lib/src/assets/flags/gp.png | Bin 0 -> 165 bytes lib/src/assets/flags/gq.png | Bin 0 -> 1184 bytes lib/src/assets/flags/gr.png | Bin 0 -> 308 bytes lib/src/assets/flags/gs.png | Bin 0 -> 2904 bytes lib/src/assets/flags/gt.png | Bin 0 -> 1370 bytes lib/src/assets/flags/gu.png | Bin 0 -> 1465 bytes lib/src/assets/flags/gw.png | Bin 0 -> 434 bytes lib/src/assets/flags/gy.png | Bin 0 -> 1006 bytes lib/src/assets/flags/hk.png | Bin 0 -> 1410 bytes lib/src/assets/flags/hm.png | Bin 0 -> 1153 bytes lib/src/assets/flags/hn.png | Bin 0 -> 528 bytes lib/src/assets/flags/hr.png | Bin 0 -> 1052 bytes lib/src/assets/flags/ht.png | Bin 0 -> 898 bytes lib/src/assets/flags/hu.png | Bin 0 -> 122 bytes lib/src/assets/flags/id.png | Bin 0 -> 147 bytes lib/src/assets/flags/ie.png | Bin 0 -> 165 bytes lib/src/assets/flags/il.png | Bin 0 -> 659 bytes lib/src/assets/flags/im.png | Bin 0 -> 1374 bytes lib/src/assets/flags/in.png | Bin 0 -> 747 bytes lib/src/assets/flags/io.png | Bin 0 -> 4687 bytes lib/src/assets/flags/iq.png | Bin 0 -> 827 bytes lib/src/assets/flags/ir.png | Bin 0 -> 2230 bytes lib/src/assets/flags/is.png | Bin 0 -> 126 bytes lib/src/assets/flags/it.png | Bin 0 -> 169 bytes lib/src/assets/flags/je.png | Bin 0 -> 1337 bytes lib/src/assets/flags/jm.png | Bin 0 -> 265 bytes lib/src/assets/flags/jo.png | Bin 0 -> 416 bytes lib/src/assets/flags/jp.png | Bin 0 -> 546 bytes lib/src/assets/flags/ke.png | Bin 0 -> 1394 bytes lib/src/assets/flags/kg.png | Bin 0 -> 1761 bytes lib/src/assets/flags/kh.png | Bin 0 -> 1558 bytes lib/src/assets/flags/ki.png | Bin 0 -> 1564 bytes lib/src/assets/flags/km.png | Bin 0 -> 912 bytes lib/src/assets/flags/kn.png | Bin 0 -> 1243 bytes lib/src/assets/flags/kp.png | Bin 0 -> 735 bytes lib/src/assets/flags/kr.png | Bin 0 -> 2270 bytes lib/src/assets/flags/kw.png | Bin 0 -> 324 bytes lib/src/assets/flags/ky.png | Bin 0 -> 2193 bytes lib/src/assets/flags/kz.png | Bin 0 -> 1869 bytes lib/src/assets/flags/la.png | Bin 0 -> 437 bytes lib/src/assets/flags/lb.png | Bin 0 -> 1199 bytes lib/src/assets/flags/lc.png | Bin 0 -> 1085 bytes lib/src/assets/flags/li.png | Bin 0 -> 1015 bytes lib/src/assets/flags/lk.png | Bin 0 -> 2496 bytes lib/src/assets/flags/lr.png | Bin 0 -> 494 bytes lib/src/assets/flags/ls.png | Bin 0 -> 932 bytes lib/src/assets/flags/lt.png | Bin 0 -> 106 bytes lib/src/assets/flags/lu.png | Bin 0 -> 106 bytes lib/src/assets/flags/lv.png | Bin 0 -> 97 bytes lib/src/assets/flags/ly.png | Bin 0 -> 404 bytes lib/src/assets/flags/ma.png | Bin 0 -> 524 bytes lib/src/assets/flags/mc.png | Bin 0 -> 98 bytes lib/src/assets/flags/md.png | Bin 0 -> 1433 bytes lib/src/assets/flags/me.png | Bin 0 -> 1858 bytes lib/src/assets/flags/mf.png | Bin 0 -> 165 bytes lib/src/assets/flags/mg.png | Bin 0 -> 192 bytes lib/src/assets/flags/mh.png | Bin 0 -> 2684 bytes lib/src/assets/flags/mk.png | Bin 0 -> 1221 bytes lib/src/assets/flags/ml.png | Bin 0 -> 165 bytes lib/src/assets/flags/mm.png | Bin 0 -> 953 bytes lib/src/assets/flags/mn.png | Bin 0 -> 846 bytes lib/src/assets/flags/mo.png | Bin 0 -> 1517 bytes lib/src/assets/flags/mp.png | Bin 0 -> 3726 bytes lib/src/assets/flags/mq.png | Bin 0 -> 1967 bytes lib/src/assets/flags/mr.png | Bin 0 -> 942 bytes lib/src/assets/flags/ms.png | Bin 0 -> 1473 bytes lib/src/assets/flags/mt.png | Bin 0 -> 583 bytes lib/src/assets/flags/mu.png | Bin 0 -> 166 bytes lib/src/assets/flags/mv.png | Bin 0 -> 429 bytes lib/src/assets/flags/mw.png | Bin 0 -> 1262 bytes lib/src/assets/flags/mx.png | Bin 0 -> 1697 bytes lib/src/assets/flags/my.png | Bin 0 -> 1024 bytes lib/src/assets/flags/mz.png | Bin 0 -> 1914 bytes lib/src/assets/flags/na.png | Bin 0 -> 1176 bytes lib/src/assets/flags/nc.png | Bin 0 -> 1246 bytes lib/src/assets/flags/ne.png | Bin 0 -> 355 bytes lib/src/assets/flags/nf.png | Bin 0 -> 1313 bytes lib/src/assets/flags/ng.png | Bin 0 -> 108 bytes lib/src/assets/flags/ni.png | Bin 0 -> 762 bytes lib/src/assets/flags/nl.png | Bin 0 -> 159 bytes lib/src/assets/flags/no.png | Bin 0 -> 260 bytes lib/src/assets/flags/np.png | Bin 0 -> 3225 bytes lib/src/assets/flags/nr.png | Bin 0 -> 460 bytes lib/src/assets/flags/nu.png | Bin 0 -> 899 bytes lib/src/assets/flags/nz.png | Bin 0 -> 1087 bytes lib/src/assets/flags/om.png | Bin 0 -> 639 bytes lib/src/assets/flags/pa.png | Bin 0 -> 752 bytes lib/src/assets/flags/pe.png | Bin 0 -> 2280 bytes lib/src/assets/flags/pf.png | Bin 0 -> 2164 bytes lib/src/assets/flags/pg.png | Bin 0 -> 1763 bytes lib/src/assets/flags/ph.png | Bin 0 -> 1348 bytes lib/src/assets/flags/pk.png | Bin 0 -> 904 bytes lib/src/assets/flags/pl.png | Bin 0 -> 146 bytes lib/src/assets/flags/pm.png | Bin 0 -> 165 bytes lib/src/assets/flags/pn.png | Bin 0 -> 2938 bytes lib/src/assets/flags/pr.png | Bin 0 -> 1211 bytes lib/src/assets/flags/ps.png | Bin 0 -> 385 bytes lib/src/assets/flags/pt.png | Bin 0 -> 2487 bytes lib/src/assets/flags/pw.png | Bin 0 -> 578 bytes lib/src/assets/flags/py.png | Bin 0 -> 659 bytes lib/src/assets/flags/qa.png | Bin 0 -> 244 bytes lib/src/assets/flags/re.png | Bin 0 -> 165 bytes lib/src/assets/flags/ro.png | Bin 0 -> 169 bytes lib/src/assets/flags/rs.png | Bin 0 -> 3393 bytes lib/src/assets/flags/ru.png | Bin 0 -> 159 bytes lib/src/assets/flags/rw.png | Bin 0 -> 1058 bytes lib/src/assets/flags/sa.png | Bin 0 -> 1856 bytes lib/src/assets/flags/sb.png | Bin 0 -> 958 bytes lib/src/assets/flags/sc.png | Bin 0 -> 536 bytes lib/src/assets/flags/sd.png | Bin 0 -> 374 bytes lib/src/assets/flags/se.png | Bin 0 -> 173 bytes lib/src/assets/flags/sg.png | Bin 0 -> 927 bytes lib/src/assets/flags/sh.png | Bin 0 -> 545 bytes lib/src/assets/flags/si.png | Bin 0 -> 563 bytes lib/src/assets/flags/sj.png | Bin 0 -> 260 bytes lib/src/assets/flags/sk.png | Bin 0 -> 1429 bytes lib/src/assets/flags/sl.png | Bin 0 -> 159 bytes lib/src/assets/flags/sm.png | Bin 0 -> 3623 bytes lib/src/assets/flags/sn.png | Bin 0 -> 555 bytes lib/src/assets/flags/so.png | Bin 0 -> 661 bytes lib/src/assets/flags/sr.png | Bin 0 -> 567 bytes lib/src/assets/flags/ss.png | Bin 0 -> 813 bytes lib/src/assets/flags/st.png | Bin 0 -> 487 bytes lib/src/assets/flags/sv.png | Bin 0 -> 984 bytes lib/src/assets/flags/sx.png | Bin 0 -> 2623 bytes lib/src/assets/flags/sy.png | Bin 0 -> 480 bytes lib/src/assets/flags/sz.png | Bin 0 -> 2397 bytes lib/src/assets/flags/tc.png | Bin 0 -> 1388 bytes lib/src/assets/flags/td.png | Bin 0 -> 165 bytes lib/src/assets/flags/tf.png | Bin 0 -> 997 bytes lib/src/assets/flags/tg.png | Bin 0 -> 628 bytes lib/src/assets/flags/th.png | Bin 0 -> 155 bytes lib/src/assets/flags/tj.png | Bin 0 -> 679 bytes lib/src/assets/flags/tk.png | Bin 0 -> 1503 bytes lib/src/assets/flags/tl.png | Bin 0 -> 667 bytes lib/src/assets/flags/tm.png | Bin 0 -> 3712 bytes lib/src/assets/flags/tn.png | Bin 0 -> 915 bytes lib/src/assets/flags/to.png | Bin 0 -> 184 bytes lib/src/assets/flags/tr.png | Bin 0 -> 879 bytes lib/src/assets/flags/tt.png | Bin 0 -> 1891 bytes lib/src/assets/flags/tv.png | Bin 0 -> 1407 bytes lib/src/assets/flags/tw.png | Bin 0 -> 853 bytes lib/src/assets/flags/tz.png | Bin 0 -> 543 bytes lib/src/assets/flags/ua.png | Bin 0 -> 147 bytes lib/src/assets/flags/ug.png | Bin 0 -> 1078 bytes lib/src/assets/flags/um.png | Bin 0 -> 754 bytes lib/src/assets/flags/us.png | Bin 0 -> 756 bytes lib/src/assets/flags/uy.png | Bin 0 -> 1884 bytes lib/src/assets/flags/uz.png | Bin 0 -> 523 bytes lib/src/assets/flags/va.png | Bin 0 -> 3176 bytes lib/src/assets/flags/vc.png | Bin 0 -> 483 bytes lib/src/assets/flags/ve.png | Bin 0 -> 814 bytes lib/src/assets/flags/vg.png | Bin 0 -> 2425 bytes lib/src/assets/flags/vi.png | Bin 0 -> 6402 bytes lib/src/assets/flags/vn.png | Bin 0 -> 723 bytes lib/src/assets/flags/vu.png | Bin 0 -> 1835 bytes lib/src/assets/flags/wf.png | Bin 0 -> 408 bytes lib/src/assets/flags/ws.png | Bin 0 -> 471 bytes lib/src/assets/flags/xk.png | Bin 0 -> 1421 bytes lib/src/assets/flags/ye.png | Bin 0 -> 159 bytes lib/src/assets/flags/yt.png | Bin 0 -> 165 bytes lib/src/assets/flags/za.png | Bin 0 -> 631 bytes lib/src/assets/flags/zm.png | Bin 0 -> 898 bytes lib/src/assets/flags/zw.png | Bin 0 -> 1472 bytes lib/src/components/phone_input/countries.dart | 1236 +++++++++++++++++ .../phone_input/countries_dialog.dart | 123 ++ .../components/phone_input/phone_input.dart | 349 +++++ lib/src/utils/extensions.dart | 11 + lib/zeta_flutter.dart | 1 + pubspec.yaml | 2 + 266 files changed, 1837 insertions(+), 1 deletion(-) create mode 100644 example/lib/pages/components/phone_input_example.dart create mode 100644 example/widgetbook/pages/components/phone_input_widgetbook.dart create mode 100644 lib/src/assets/flags/ad.png create mode 100644 lib/src/assets/flags/ae.png create mode 100644 lib/src/assets/flags/af.png create mode 100644 lib/src/assets/flags/ag.png create mode 100644 lib/src/assets/flags/ai.png create mode 100644 lib/src/assets/flags/al.png create mode 100644 lib/src/assets/flags/am.png create mode 100644 lib/src/assets/flags/an.png create mode 100644 lib/src/assets/flags/ao.png create mode 100644 lib/src/assets/flags/aq.png create mode 100644 lib/src/assets/flags/ar.png create mode 100644 lib/src/assets/flags/as.png create mode 100644 lib/src/assets/flags/at.png create mode 100644 lib/src/assets/flags/au.png create mode 100644 lib/src/assets/flags/aw.png create mode 100644 lib/src/assets/flags/ax.png create mode 100644 lib/src/assets/flags/az.png create mode 100644 lib/src/assets/flags/ba.png create mode 100644 lib/src/assets/flags/bb.png create mode 100644 lib/src/assets/flags/bd.png create mode 100644 lib/src/assets/flags/be.png create mode 100644 lib/src/assets/flags/bf.png create mode 100644 lib/src/assets/flags/bg.png create mode 100644 lib/src/assets/flags/bh.png create mode 100644 lib/src/assets/flags/bi.png create mode 100644 lib/src/assets/flags/bj.png create mode 100644 lib/src/assets/flags/bl.png create mode 100644 lib/src/assets/flags/bm.png create mode 100644 lib/src/assets/flags/bn.png create mode 100644 lib/src/assets/flags/bo.png create mode 100644 lib/src/assets/flags/bq.png create mode 100644 lib/src/assets/flags/br.png create mode 100644 lib/src/assets/flags/bs.png create mode 100644 lib/src/assets/flags/bt.png create mode 100644 lib/src/assets/flags/bv.png create mode 100644 lib/src/assets/flags/bw.png create mode 100644 lib/src/assets/flags/by.png create mode 100644 lib/src/assets/flags/bz.png create mode 100644 lib/src/assets/flags/ca.png create mode 100644 lib/src/assets/flags/cc.png create mode 100644 lib/src/assets/flags/cd.png create mode 100644 lib/src/assets/flags/cf.png create mode 100644 lib/src/assets/flags/cg.png create mode 100644 lib/src/assets/flags/ch.png create mode 100644 lib/src/assets/flags/ci.png create mode 100644 lib/src/assets/flags/ck.png create mode 100644 lib/src/assets/flags/cl.png create mode 100644 lib/src/assets/flags/cm.png create mode 100644 lib/src/assets/flags/cn.png create mode 100644 lib/src/assets/flags/co.png create mode 100644 lib/src/assets/flags/cr.png create mode 100644 lib/src/assets/flags/cu.png create mode 100644 lib/src/assets/flags/cv.png create mode 100644 lib/src/assets/flags/cw.png create mode 100644 lib/src/assets/flags/cx.png create mode 100644 lib/src/assets/flags/cy.png create mode 100644 lib/src/assets/flags/cz.png create mode 100644 lib/src/assets/flags/de.png create mode 100644 lib/src/assets/flags/dj.png create mode 100644 lib/src/assets/flags/dk.png create mode 100644 lib/src/assets/flags/dm.png create mode 100644 lib/src/assets/flags/do.png create mode 100644 lib/src/assets/flags/dz.png create mode 100644 lib/src/assets/flags/ec.png create mode 100644 lib/src/assets/flags/ee.png create mode 100644 lib/src/assets/flags/eg.png create mode 100644 lib/src/assets/flags/eh.png create mode 100644 lib/src/assets/flags/er.png create mode 100644 lib/src/assets/flags/es.png create mode 100644 lib/src/assets/flags/et.png create mode 100644 lib/src/assets/flags/eu.png create mode 100644 lib/src/assets/flags/fi.png create mode 100644 lib/src/assets/flags/fj.png create mode 100644 lib/src/assets/flags/fk.png create mode 100644 lib/src/assets/flags/fm.png create mode 100644 lib/src/assets/flags/fo.png create mode 100644 lib/src/assets/flags/fr.png create mode 100644 lib/src/assets/flags/ga.png create mode 100644 lib/src/assets/flags/gb-eng.png create mode 100644 lib/src/assets/flags/gb-nir.png create mode 100644 lib/src/assets/flags/gb-sct.png create mode 100644 lib/src/assets/flags/gb-wls.png create mode 100644 lib/src/assets/flags/gb.png create mode 100644 lib/src/assets/flags/gd.png create mode 100644 lib/src/assets/flags/ge.png create mode 100644 lib/src/assets/flags/gf.png create mode 100644 lib/src/assets/flags/gg.png create mode 100644 lib/src/assets/flags/gh.png create mode 100644 lib/src/assets/flags/gi.png create mode 100644 lib/src/assets/flags/gl.png create mode 100644 lib/src/assets/flags/gm.png create mode 100644 lib/src/assets/flags/gn.png create mode 100644 lib/src/assets/flags/gp.png create mode 100644 lib/src/assets/flags/gq.png create mode 100644 lib/src/assets/flags/gr.png create mode 100644 lib/src/assets/flags/gs.png create mode 100644 lib/src/assets/flags/gt.png create mode 100644 lib/src/assets/flags/gu.png create mode 100644 lib/src/assets/flags/gw.png create mode 100644 lib/src/assets/flags/gy.png create mode 100644 lib/src/assets/flags/hk.png create mode 100644 lib/src/assets/flags/hm.png create mode 100644 lib/src/assets/flags/hn.png create mode 100644 lib/src/assets/flags/hr.png create mode 100644 lib/src/assets/flags/ht.png create mode 100644 lib/src/assets/flags/hu.png create mode 100644 lib/src/assets/flags/id.png create mode 100644 lib/src/assets/flags/ie.png create mode 100644 lib/src/assets/flags/il.png create mode 100644 lib/src/assets/flags/im.png create mode 100644 lib/src/assets/flags/in.png create mode 100644 lib/src/assets/flags/io.png create mode 100644 lib/src/assets/flags/iq.png create mode 100644 lib/src/assets/flags/ir.png create mode 100644 lib/src/assets/flags/is.png create mode 100644 lib/src/assets/flags/it.png create mode 100644 lib/src/assets/flags/je.png create mode 100644 lib/src/assets/flags/jm.png create mode 100644 lib/src/assets/flags/jo.png create mode 100644 lib/src/assets/flags/jp.png create mode 100644 lib/src/assets/flags/ke.png create mode 100644 lib/src/assets/flags/kg.png create mode 100644 lib/src/assets/flags/kh.png create mode 100644 lib/src/assets/flags/ki.png create mode 100644 lib/src/assets/flags/km.png create mode 100644 lib/src/assets/flags/kn.png create mode 100644 lib/src/assets/flags/kp.png create mode 100644 lib/src/assets/flags/kr.png create mode 100644 lib/src/assets/flags/kw.png create mode 100644 lib/src/assets/flags/ky.png create mode 100644 lib/src/assets/flags/kz.png create mode 100644 lib/src/assets/flags/la.png create mode 100644 lib/src/assets/flags/lb.png create mode 100644 lib/src/assets/flags/lc.png create mode 100644 lib/src/assets/flags/li.png create mode 100644 lib/src/assets/flags/lk.png create mode 100644 lib/src/assets/flags/lr.png create mode 100644 lib/src/assets/flags/ls.png create mode 100644 lib/src/assets/flags/lt.png create mode 100644 lib/src/assets/flags/lu.png create mode 100644 lib/src/assets/flags/lv.png create mode 100644 lib/src/assets/flags/ly.png create mode 100644 lib/src/assets/flags/ma.png create mode 100644 lib/src/assets/flags/mc.png create mode 100644 lib/src/assets/flags/md.png create mode 100644 lib/src/assets/flags/me.png create mode 100644 lib/src/assets/flags/mf.png create mode 100644 lib/src/assets/flags/mg.png create mode 100644 lib/src/assets/flags/mh.png create mode 100644 lib/src/assets/flags/mk.png create mode 100644 lib/src/assets/flags/ml.png create mode 100644 lib/src/assets/flags/mm.png create mode 100644 lib/src/assets/flags/mn.png create mode 100644 lib/src/assets/flags/mo.png create mode 100644 lib/src/assets/flags/mp.png create mode 100644 lib/src/assets/flags/mq.png create mode 100644 lib/src/assets/flags/mr.png create mode 100644 lib/src/assets/flags/ms.png create mode 100644 lib/src/assets/flags/mt.png create mode 100644 lib/src/assets/flags/mu.png create mode 100644 lib/src/assets/flags/mv.png create mode 100644 lib/src/assets/flags/mw.png create mode 100644 lib/src/assets/flags/mx.png create mode 100644 lib/src/assets/flags/my.png create mode 100644 lib/src/assets/flags/mz.png create mode 100644 lib/src/assets/flags/na.png create mode 100644 lib/src/assets/flags/nc.png create mode 100644 lib/src/assets/flags/ne.png create mode 100644 lib/src/assets/flags/nf.png create mode 100644 lib/src/assets/flags/ng.png create mode 100644 lib/src/assets/flags/ni.png create mode 100644 lib/src/assets/flags/nl.png create mode 100644 lib/src/assets/flags/no.png create mode 100644 lib/src/assets/flags/np.png create mode 100644 lib/src/assets/flags/nr.png create mode 100644 lib/src/assets/flags/nu.png create mode 100644 lib/src/assets/flags/nz.png create mode 100644 lib/src/assets/flags/om.png create mode 100644 lib/src/assets/flags/pa.png create mode 100644 lib/src/assets/flags/pe.png create mode 100644 lib/src/assets/flags/pf.png create mode 100644 lib/src/assets/flags/pg.png create mode 100644 lib/src/assets/flags/ph.png create mode 100644 lib/src/assets/flags/pk.png create mode 100644 lib/src/assets/flags/pl.png create mode 100644 lib/src/assets/flags/pm.png create mode 100644 lib/src/assets/flags/pn.png create mode 100644 lib/src/assets/flags/pr.png create mode 100644 lib/src/assets/flags/ps.png create mode 100644 lib/src/assets/flags/pt.png create mode 100644 lib/src/assets/flags/pw.png create mode 100644 lib/src/assets/flags/py.png create mode 100644 lib/src/assets/flags/qa.png create mode 100644 lib/src/assets/flags/re.png create mode 100644 lib/src/assets/flags/ro.png create mode 100644 lib/src/assets/flags/rs.png create mode 100644 lib/src/assets/flags/ru.png create mode 100644 lib/src/assets/flags/rw.png create mode 100644 lib/src/assets/flags/sa.png create mode 100644 lib/src/assets/flags/sb.png create mode 100644 lib/src/assets/flags/sc.png create mode 100644 lib/src/assets/flags/sd.png create mode 100644 lib/src/assets/flags/se.png create mode 100644 lib/src/assets/flags/sg.png create mode 100644 lib/src/assets/flags/sh.png create mode 100644 lib/src/assets/flags/si.png create mode 100644 lib/src/assets/flags/sj.png create mode 100644 lib/src/assets/flags/sk.png create mode 100644 lib/src/assets/flags/sl.png create mode 100644 lib/src/assets/flags/sm.png create mode 100644 lib/src/assets/flags/sn.png create mode 100644 lib/src/assets/flags/so.png create mode 100644 lib/src/assets/flags/sr.png create mode 100644 lib/src/assets/flags/ss.png create mode 100644 lib/src/assets/flags/st.png create mode 100644 lib/src/assets/flags/sv.png create mode 100644 lib/src/assets/flags/sx.png create mode 100644 lib/src/assets/flags/sy.png create mode 100644 lib/src/assets/flags/sz.png create mode 100644 lib/src/assets/flags/tc.png create mode 100644 lib/src/assets/flags/td.png create mode 100644 lib/src/assets/flags/tf.png create mode 100644 lib/src/assets/flags/tg.png create mode 100644 lib/src/assets/flags/th.png create mode 100644 lib/src/assets/flags/tj.png create mode 100644 lib/src/assets/flags/tk.png create mode 100644 lib/src/assets/flags/tl.png create mode 100644 lib/src/assets/flags/tm.png create mode 100644 lib/src/assets/flags/tn.png create mode 100644 lib/src/assets/flags/to.png create mode 100644 lib/src/assets/flags/tr.png create mode 100644 lib/src/assets/flags/tt.png create mode 100644 lib/src/assets/flags/tv.png create mode 100644 lib/src/assets/flags/tw.png create mode 100644 lib/src/assets/flags/tz.png create mode 100644 lib/src/assets/flags/ua.png create mode 100644 lib/src/assets/flags/ug.png create mode 100644 lib/src/assets/flags/um.png create mode 100644 lib/src/assets/flags/us.png create mode 100644 lib/src/assets/flags/uy.png create mode 100644 lib/src/assets/flags/uz.png create mode 100644 lib/src/assets/flags/va.png create mode 100644 lib/src/assets/flags/vc.png create mode 100644 lib/src/assets/flags/ve.png create mode 100644 lib/src/assets/flags/vg.png create mode 100644 lib/src/assets/flags/vi.png create mode 100644 lib/src/assets/flags/vn.png create mode 100644 lib/src/assets/flags/vu.png create mode 100644 lib/src/assets/flags/wf.png create mode 100644 lib/src/assets/flags/ws.png create mode 100644 lib/src/assets/flags/xk.png create mode 100644 lib/src/assets/flags/ye.png create mode 100644 lib/src/assets/flags/yt.png create mode 100644 lib/src/assets/flags/za.png create mode 100644 lib/src/assets/flags/zm.png create mode 100644 lib/src/assets/flags/zw.png create mode 100644 lib/src/components/phone_input/countries.dart create mode 100644 lib/src/components/phone_input/countries_dialog.dart create mode 100644 lib/src/components/phone_input/phone_input.dart diff --git a/example/lib/home.dart b/example/lib/home.dart index a122e837..345ee042 100644 --- a/example/lib/home.dart +++ b/example/lib/home.dart @@ -15,6 +15,7 @@ import 'package:zeta_example/pages/components/dialpad_example.dart'; import 'package:zeta_example/pages/components/dropdown_example.dart'; import 'package:zeta_example/pages/components/list_item_example.dart'; import 'package:zeta_example/pages/components/navigation_bar_example.dart'; +import 'package:zeta_example/pages/components/phone_input_example.dart'; import 'package:zeta_example/pages/components/radio_example.dart'; import 'package:zeta_example/pages/components/stepper_example.dart'; import 'package:zeta_example/pages/components/switch_example.dart'; @@ -61,6 +62,7 @@ final List components = [ Component(RadioButtonExample.name, (context) => const RadioButtonExample()), Component(SwitchExample.name, (context) => const SwitchExample()), Component(DateInputExample.name, (context) => const DateInputExample()), + Component(PhoneInputExample.name, (context) => const PhoneInputExample()), Component(DialogExample.name, (context) => const DialogExample()), ]; diff --git a/example/lib/pages/components/phone_input_example.dart b/example/lib/pages/components/phone_input_example.dart new file mode 100644 index 00000000..49ccf0c0 --- /dev/null +++ b/example/lib/pages/components/phone_input_example.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:zeta_example/widgets.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +class PhoneInputExample extends StatefulWidget { + static const String name = 'PhoneInput'; + + const PhoneInputExample({Key? key}) : super(key: key); + + @override + State createState() => _PhoneInputExampleState(); +} + +class _PhoneInputExampleState extends State { + String? _errorText; + + @override + Widget build(BuildContext context) { + return ExampleScaffold( + name: 'Phone Input', + child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('Rounded', style: ZetaTextStyles.titleMedium), + ), + Padding( + padding: const EdgeInsets.all(20), + child: ZetaPhoneInput( + label: 'Phone number', + hint: 'Enter your phone number', + hasError: _errorText != null, + errorText: _errorText, + onChanged: (value) { + if (value?.isEmpty ?? true) setState(() => _errorText = null); + print(value); + }, + countries: ['US', 'GB', 'DE', 'AT', 'FR', 'IT', 'BG'], + ), + ), + Divider(color: Colors.grey[200]), + Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('Sharp', style: ZetaTextStyles.titleMedium), + ), + Padding( + padding: const EdgeInsets.all(20), + child: ZetaPhoneInput( + label: 'Phone number', + hint: 'Enter your phone number', + countryDialCode: '+44', + phoneNumber: '987654321', + hasError: _errorText != null, + errorText: _errorText, + onChanged: (value) { + if (value?.isEmpty ?? true) return setState(() => _errorText = null); + }, + rounded: false, + ), + ), + Divider(color: Colors.grey[200]), + Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('Disabled', style: ZetaTextStyles.titleMedium), + ), + Padding( + padding: const EdgeInsets.all(20), + child: ZetaPhoneInput( + label: 'Phone number', + hint: 'Enter your phone number', + enabled: false, + ), + ), + ], + ), + ), + ); + } +} diff --git a/example/widgetbook/main.dart b/example/widgetbook/main.dart index 26299242..6911d1a3 100644 --- a/example/widgetbook/main.dart +++ b/example/widgetbook/main.dart @@ -22,6 +22,7 @@ import 'pages/components/list_item_widgetbook.dart'; import 'pages/components/navigation_bar_widgetbook.dart'; import 'pages/components/pagination_widgetbook.dart'; import 'pages/components/password_input_widgetbook.dart'; +import 'pages/components/phone_input_widgetbook.dart'; import 'pages/components/progress_widgetbook.dart'; import 'pages/components/radio_widgetbook.dart'; import 'pages/components/stepper_widgetbook.dart'; @@ -118,11 +119,12 @@ class HotReload extends StatelessWidget { builder: (context) => snackBarUseCase(context), ), WidgetbookUseCase(name: 'Date Input', builder: (context) => dateInputUseCase(context)), + WidgetbookUseCase(name: 'Tabs', builder: (context) => tabsUseCase(context)), + WidgetbookUseCase(name: 'Phone Input', builder: (context) => phoneInputUseCase(context)), WidgetbookUseCase( name: 'Stepper', builder: (context) => stepperUseCase(context), ), - WidgetbookUseCase(name: 'Tabs', builder: (context) => tabsUseCase(context)), WidgetbookUseCase(name: 'Dialog', builder: (context) => dialogUseCase(context)), ]..sort((a, b) => a.name.compareTo(b.name)), ), diff --git a/example/widgetbook/pages/components/phone_input_widgetbook.dart b/example/widgetbook/pages/components/phone_input_widgetbook.dart new file mode 100644 index 00000000..c63f423f --- /dev/null +++ b/example/widgetbook/pages/components/phone_input_widgetbook.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +import '../../test/test_components.dart'; + +Widget phoneInputUseCase(BuildContext context) { + final countries = context.knobs.string( + label: 'ISO 3166-1 alpha-2 county codes', + initialValue: '', + ); + final rounded = context.knobs.boolean(label: 'Rounded', initialValue: true); + final enabled = context.knobs.boolean(label: 'Enabled', initialValue: true); + return WidgetbookTestWidget( + widget: StatefulBuilder( + builder: (context, setState) { + return Padding( + padding: const EdgeInsets.all(ZetaSpacing.x5), + child: ZetaPhoneInput( + rounded: rounded, + enabled: enabled, + label: 'Phone number', + hint: 'Enter your phone number', + countries: countries.isEmpty ? null : countries.toUpperCase().split(','), + ), + ); + }, + ), + ); +} diff --git a/lib/src/assets/flags/ad.png b/lib/src/assets/flags/ad.png new file mode 100644 index 0000000000000000000000000000000000000000..fdc41f6a1d7a9bfcb587e942ed141f2520c34d25 GIT binary patch literal 2138 zcmV-g2&MOlP)pGqAquU*z)rFLyk4(#{moCk^6IB--g3`+efeB{*@mt6`^{BPz4?|W_51Fv z8cRx)3GMX?!60*bROjY}) z%{M<-LZRJ)#Aws;9h>V!`UBzRY-TOlu=No{4?4Z7mvaqJMo}t3y|JUy%PM0H#398( zgoV|Ot?t~8ln}LjPRENK*0iZ9TCR7m}R#1GLo9aFm3$2@+zggLY`NUkxt@>^SXJqieSzHx@`0bDTl*68UD^|Hfycx1(y*7 zYT!hR-};i=o$rf&i|0R{%re3?p+JeD2#gtOfN?_sC^dwDQ6}SVu2yS9K7;S}#&+(x zLe#6DhdTuze z8m(oUc06Inwl(cqRVGTqsSrn>SOBpJPUL^8_^=24GtU@_HCtOd*Sy1~Ef1eMk{>oK zt>D1nJMw?RqvLXsq(#sY^tRLxrUj z34&2WiLohjs5vza64&)Eyd>IoJy_=h5U?N8|Mjmjm){2db_l>Zjl)V@&?i+mAeanTZb!cE79jt^Lg(o|C=p9f}Wr1TU1~Z^vyr zU&?aZvRvDMVRXQm8Y(Qx%%X{Pl(AqCN{T_Rg9N*`{IY+`cO-pauy@zYhu&?n1sR3Y z?|qx-HjDDgLzDANh}^4-L17P$6B%Wd;WXFu_t$@-dtYt=KAzIE0sreyVp44k>@ye zt2(~@x{c@l|B9W|Q}DZv&0IWp;GT)rE)1zQfUK>0Y_t5 zn!~BjsJX2yW{?13fPHkol&pK*VjRPzqh< z)JwJ>9UxMnv%MW95$jAY)0uAPN*O6kq8APN&PX{NHZ0o;KnZ5^OwMMs?00);h!CP5 z=B&_LuA1awRhYpAuR0Kga;sZ~)XDvlCH10_`y#?|EuESHN&h&Z-*GK7<%ZHsbo z2O(61p_jLdqeTShbpm5_oFr0d?l68Liz*>iBJHeu(#l{QiC(L3yH=7UrRvC{)eGI6 zE#kxg7Q7u^Ru180hzOIbe-i}I56<>G0kv7aT*y}nNf2voPKa2x-D`CE9p7>|AR}lj9 z-ka=XV~8{!x4DiJAtYr)Yn6yZ znqnMNI5T2!W@KCOWfy#T_nr$F>v#O~v}iA?Zm%WTbI;wJEhsoMIukGZ4MPiwc5Hd3 zUG~f1%*%B}dYa@smSUw?DOQS=mSUw?DOQS=Vx?GVDOQS=Vx?FqR*IE&90l$o&vTgk Qe*gdg07*qoM6N<$f}5ueZ2$lO literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ae.png b/lib/src/assets/flags/ae.png new file mode 100644 index 0000000000000000000000000000000000000000..8e0ae66541c1d1d0ba10e76b7356605d8c4a867c GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!VDxMq?3Drlyrbki0gkKqgX$8edm8LPyqv= z7!XX6ySE)kah3%61^@ql?Ek-GNB{p@%eONWC}`^G;uunKD>=!5si)}(gBshUgDa*5 z>K+c@mi*bOq3g7`(PmX@2=|P|E<6iDPG{`t$&&PpVpw!oaKX~d`LaL*7(8A5T-G@y GGywoW968tk literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/af.png b/lib/src/assets/flags/af.png new file mode 100644 index 0000000000000000000000000000000000000000..bb620b1b32463d933c545f7289bcab5d3416cbf6 GIT binary patch literal 2662 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 wg)iu00{{R3U6oMi00087P)t-s00026 z4j}*l009920s;U70{{dA00jg91_c2J1_1~M0SO2J3kd-Y3jq!c0S^rU6cGXy5&{+z z0v8kl7!?8=7Xls{10Nd$ARGfB9RnmE10^5>CLseSA_FQU1S}>5FDL{vECe?%1v@eY zJu?PAHU>X820%ClK{f_KI0i>O21q^!Pecb%Mh8+x2UAA}R!Rt0O9xm?2w6-BT1^OB zP6%C42wqVLWmXAiSP5uZ32R&la$*W~WeRp?3U_7;cV`QDXA6313w>(~eryYWZ3~2P z42E+Ih;6Sg$|sC4xow-q>T=yj}NDi52%n2 zs*(?^ln z_tX~n)fV~I7T820&JiZwSRl|DCH2M^(H|wx6ea7H8`wi4&Jrf*i5%88BkGhK&lD!n zA|=olCete<+)*LW7$)__7ta+X)Gs6V%@^QfANkc5)iNa6MIz;S9?={n=Y}2Vh#b)! zCD9%v+DIYVNg?Wz8`Uu+);A;BKqBah9BmL2+)*Iwl^p7k8`d==-BcmnRw3P2A?ueL zux}OKTOjVG8jCy>@2MK^su}OB8Q)$Y@T?l}t{K-jBk{5s@w6H8wi)ub8PFRg^SBxF zyBKE(6X0bZ^}rbQ#22@D72#?h)GQ?S%NO^|7vpgs_s_Wvgb#-;Aw z>+bIEu0N#xI+wehE}%&h&W5}T@&ppe5iG$+uyI5*q7jW~L?e!BB**OX?Mp^2as%7} zRzWG!1nn@R6gfD0BjqW-T2+OZCg+8_J>cZMAsH$C)<8q;$Dz(W1K5@RUCbh*$o}%1DwK_I zgOGJm6R*JOlyoE@r1PIH@W5pwj&;5gUKZ1$w*Xfz;?Hpwn4FvQo3ug%)t%tQyA0Egem>_xR_TAEu z5t3{aM$q}4{Ob7Dn>1?9Np3JQ1FKQ)dWZ) zceK3~^BE7lSI@#lJ0hWQYpImmZ7EH*2%}R zpP0iW8TGsx8=u|2j65+1x#4}9FN>gjhpCkrrmjww-<8QCH^Sr>jR>*}X!e~u2RcL% zl)v=ft~9yG^}7{y{)YexEiXO=t%@W9r~qs(mo0fFGVk+hPR)$`XD$B7ypnAM^%sHR vtRv`SRF`!G&+SSkM7A7~LvlzCxsLt-QDo&i#0(Rs00000NkvXXu0mjfHx)$a literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/aq.png b/lib/src/assets/flags/aq.png new file mode 100644 index 0000000000000000000000000000000000000000..827282f7eb8b4339b682945bce4f6acd597750fe GIT binary patch literal 6114 zcmV<87aiz{P)PmUE8*8+qUm#+qP|+W81cE+qUQZ)~)yI<#v)jmE@brWc50$)2Xhm+O_fD zs6K_4fBM*(j~^d<%hv5XKlsD*s=Dj-Upnch$K87I?Jb^aGjPb*nXA@rI(YEl?mc_g zZ``_g`MPOymabg0(c#2b7yYDxW*WQ2jc(UTRS*5hPcGQDW7qfpePccIt&3QW);&hG z=sKdwX0QI-2?l!I1MLTnnz3v5-sP(|bm}+mjwidFbmf!Z``3-{{MH%8jURZSx1;!q z2AXN?7B{+m=dL}v(xGl&_1WW_96+0%#yQ+cBZ>9lAD?f<%%oC-FaP1nd!FrqQ`W5C zjIw83_w1*Cb;&C}b6mD%F0nF)+jXKV9qLx+9`U6=Tv@68kB+%HNI-*$<+$Z#UpeLcTV9+rbFopr&~fO`j=$}dpUn~|ky!bMZguVv9yD>rA`kWGOoIv27hQXQ zJLioj)*HTb@{$$nPQ2pD@b&HAIGuFRHABbFI`)!B-}vQ|W6MK9tax~k$9bqnBaLB% z>!)7*^rB^J>9`|;SdODFdW0-|=!fUs_C%LWTX*yvJoyJl-4uU4Jj9BJM;m})7|ch0 zeE#ZnoBw(KL#`hw#3F-p7OvdBV;AlFwLf1SE;fo-;rRMrt}&SHJ9f{UzufSS6k>h; zx0eqdGjqv`^}BZO`NYpJa^*-MmV*%hJE(|3qh}aogNa3VUVUHN&0BX+Qm^~siO;ql zY%z}cdS zam)61f9I^oWo%`iVN+Z=+{F6HvA3>Rz44LeeXU#Z^~>*SHFeHXD6z4`f`MnuTMp}I zJcmbH^fPRZ$KfN^S=T?eVe_`KCg!zYIC1WxRp;FJLSu<_!7a^ZEm-lI&!15GlVPvl zw9OO_IkA`(5Omq9^CAiAZP@aTZ=TU8V!iX*XClY%PP@BO1B2%6yX`Xd!vhf#w zclnN8yZx>Hjx`r=2Nge!j1Kr@Zql5hTnBJO{_ zSK=T|$D}MwqC6H7U1ic2cq;Lrv-oKAS1H|vD9n8RlGS_m?i)US_I=Ow6hB~IKl0-X z{&2=U&ASZ0=(gq#4PNZzyu~x^20zlg&qK}o5U!gZ>2$-x9a&+Wl+N&P=R6i3Ouu z?Rs4H-=2CGhY>r7QdZLUREEh{ORVr2F=5UnceZ@0&7d(;<_#Dz{n`iHk_&BThIznp#ld%kn_ zH~)6sT~BqVgKEYc{Gm#`iBJUr#^X6!xDSi51%ahE>!$zNQ& zedq3P{Pmhr&3gTV?ZZ^-B-Yre3#h-v%h%#xtZ~KNt>5~!R2`r3hxm_I-P;peMw-Bzf#MXz^W0;6N+a#=! zG5IMElQl5hTOaRIti|8*wNu4WMNpN$$0PzaED&i)PYcLd3jxd@&B3Sj~FMAwWDq6!2 z|Hvw_V0)kMFoZo07te%25-7#`;`~ZJ0M3or@6BI5RphIFV&MYMt@Nu%By2o#;@skk zP@caOMOmY1$`VDvf=ekh0UZSSJwtRDCL+C8-qQw)x#$7;(ub!iQ7THh5fGU`eI3?G zEct4BecZGKIc+-j9f!YyJZ3)BS@G~p(_~G#L!YtSQqw2PdBl=Fvfwe}Am#~Gvc%%E zKRo*89F2}+gY@Me^oz8plPR;8)K9E`U+^$*vB_pnw;jaPa4<91`I~WIe?8}Z-jz|& zYcbz}6g;Pj#Ns{hzcMKN(mPvPoTD##^n3rlp)5+k(s2>;4}*qO(A^r;Ni5d(tzSPa z)JZh?x#qrhEGE!jd=U%`GJ$GP4tFOLe&{u1vKz}2iyqxU z$d{~7{qho4C>^*OHoS_7obTJeADKX>-b1J4r^tqln~f}Ghy}bt7Ns|M##jD$Rdh<| zFD!P-)ldKP{0G_B<1T%?O4JIYc4c$`;)p6azzii7`MKX*Mz}&VC%(GqCkuW&yR4F}5 zC_oLq1!saDJ?7#^AtT=C^tsE|nXn$k z67<)%{&roH(LrQE-2WmLR}Q|&Ps7m^@xe5!j;_A9&GJ?2=nfb?J$+4b$4y)K+RvZx zwr`vU?!to3NE(Qy*!oMzf_|0EA#o(hjH#y)JI}N3m|DRaY zv-|VC0g#vBk80wwJ6mDV;KbhYXs79Oma^jcTupY`^%~yr=e!^|M8iw+JiN&nKwaAfQ5eZU? zPZ13^!ZTzsEryJlkyAW#!sSl{mB;jm(63#;8N8-((}_hNi&d=KxYh0M z)m1*FV0V#42ouhX7g5>ZO(A?e{n{qrA+jJ&sIM#pa~`l_{t<3qhM+1aE;BMV_^zkB zty;UWWw(+1H7!FN&Ps|C(a@xrKWMg*Ky(Lnz^-2pl9>h<$_}!};7J6Tgp#k6h&ktMz{u%N3V@G_*mR@TXXq5# z$Dnf%BVV7P!B*{ikBQ7r`mjS;$%0GriN*0OE3=Xpu1AFsqL|o2tJiH(>f{mP;H+CBm|&(XQUJgyhaiL@6_nu%`=+PZdJdWV zw{!0oKVuWP0)UUj%o!FKsST7s4CRW6KxrE|ljl^4SOLM7l_m*V-Tw4AouBSO>Bx&^ z2bgYnsAJ;9?|iD8oP5Ey1v5{)2biLdVmv2Q@Z_^S*bPhu{X(1aGdLWXHqnDAB^Ik6 zeWQ$$R?xr?W1V~zO2b)IAyvlxg^okSRLF12#M#XPI4UfcNG$%R#Vn31G7kBg3p1Ke z^!`KKg0h&saAhUmI1-Cmg_1H}H+u^1i5jVa;Sz_7tQFPnap}aOf1<9Wj{>9uUn{{T zrn8`_(I*m%Jt_tnG@r>w$twMTS7b2LfbBc?rWg2VhKr|4qb`wHBDAb(B!RL=*Xb|n zIU{r);XwhTCw_=k^f5&Q@D7SU*I`Jdk_gQT7BgMDi#LWvh=)W-&VU3Ac*tdc66&R= zNFSw%QpNGSKr99bswDLxs3LLA-g8mGtFj&Px0Q{g6N^~k`V7T$RK8yefPZ@GRF9eH z6mTg!0I#;f^jEIgR6DU8 z*FD(br6m^W!&CoQwNMCp<;{v3)c;7)AQQLMgQiTu?kx){*Al7CX|+jo9X&&$=%YpW@BH=ov?vo+5o2LFO|E zMOk3cL><=cNM}nZ@*L@!Lo}g&CIo7jNct5A<%DQLuAI3kRrx$*Q3STNG(;mX8MZNI zZV~5UJwk7FglLAAUbkiyLp0R}|4@XTDlOp_o+cWVf`9UTMZA#xs5;>xR|@{oQ=(2~ zgMZ);K7}^qYikJpmDV9iypxiO!M|$5%EX7LXD;#*PPyu-(s%%lFi$aGaU!a!?6}=U z4M{pwB9{6j4Jvu;@{crtM+6O+9#+OdWee*qYNfDp)d>q~tL*kT>=so<#(t@-$Vph> zN(MVWVL_w+@r-+O5*A~pE;Ny7TT>Diuzu#Eic_0sauOC*r@~kR*1Z(GNqohpmLenY zw`?v;beOgxLHWcY;1--(%uj`hK}XbhY4^+b3 z^ml2J)i~s$!b=z&A}g_lJb+R@d|NCNU|oU?=#huSf*4A?|Qn2zb9T% z(VNSp@6|0Sb+W1{#6l*!e;|*@Qz%tQv_n-kPZKHzZgSH1u{~KyO5exAkaQQ>Pb((8}(m(cSK(`=BP=c!H+hp9MGDN`)cuL**qE zh9D|lNZf!B>$yTuQLbD8Zmh2llh6McF6o1wetPV!)s`In@aUUpaktY`i6uv2CyAO; zb|#h_l{SOgl1h$JirGqw>p>L}bbB1c3^06ruR{uqmThP30a{>^I%u+(4YJovYPTm{StdoGlA-hH^*xhH|o; z*--Amdamb{P&$F{N{K=bQc3JavF)RnT`ZdiLO$%4vY{MKMl}Kv-^g4Dex`@n25aRH z#j6UGsQFsw`?GR(>(c=2c+3Vu38q&zKEuHAQkr~KLG%+fCh3S1c0v^5S?NnKVEUS0 zf&qWQtMI+Y189s(J;Wk7IhDwEdz#h4rEADzcnL;n>ckj~=a$Dh*YFYy{3L{hPz8%n zNhLF`FU9LswhCbSS|_pc@qrK(GFccHy{x9^Hju1*TMT%Ela(AGn(ENLxJN)WZ2K3_ z;aJp6EVt(be7Lk?39tL&Ng{%!AuzG?`d{3W`bsG9J$;@T^lv7Rns^SW46lTOZwYC& z#9}uD{31kPLkODaFovS|;UflwX7p0TYwm07q0ZSW!T9u7LYZb=uY`&(+N|wmV^lH& zj5NhB8zY!>hnfHSpRz*;&bQ~y|VW`hB%9- z4BiM2_bbjZe8wO0`UK(4hQH!GLcEMO1EU}ASDeS!uJDIAQxVYspS)0csw3g$`Rby= zHpYg(JU{zy8H6WWh9|Az(AAYF#IdX^bnX!zBrM~h9-W_9Y8bIZAgL-fV>uNPf?45T_Ho3-4^(H= z|1bM=qAMNhR_7i8m#3#J8$&E5F`V8Mzf$~~cq+3}_Q~6zeHE9J5!d;&`NYydGmYKi zMz`xkS2}cE=jqAth7n61Mf_7;U9~UA<^U*HQ-&|+hA%=fuK1T|4CHMaq{E4?E{5!b oW*WQ2jc(UTwK=Ey|IO(C0CZ;QWQOwTwg3PC07*qoM6N<$g8d&PCIA2c literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ar.png b/lib/src/assets/flags/ar.png new file mode 100644 index 0000000000000000000000000000000000000000..846a2bc14c892f405f425e076e31714cca52e34b GIT binary patch literal 991 zcmV<510ei~P)jx;m!K>^X0~!?%c)h+r#9?pZxjv{QCLl(6aI6*6Y!#CLC{<<;uZulVul@Z7-g+qUe}sN=qYn&!fV>dc+synooHSkaU{#f(3}ej?PLPS&DN<-mvO%%14Tk?hl^`1A4q{{G{{ zo94)v?%2HFuUy`nd(V0osqEqb9u;$2@@#NF;^nn&5EVBouc@88tx*0lEQ+yDLi>d~y`#EIdyY}BDw$cHBK zuMXFe4&R#$;hhcFkPY##4#9a6)Sgn|wrk?Md-2}H_ww%R*S_MxlH|XJ;J0(sqgc+1 z8s?x5=%5YgqYdMq4%DJp-?nn%!jbIQzwq6};<@~{r%pbX@m49JHl z)S_4C#EIz9tMA^_-@1IynMdNB4&d~d>$&u*GoaMrZ)}c?-pHISl zA;^nB&y+sdr&sFEo#nxV>B^b=_xAeq?CsXI?9{90x@_dXgy6h@)}~wDv2fb1Y~;j? zE7nfrsTeT=gFYv$ercFg6`C)@7lHR+rI48vGL^8>CdR;z=Z47x9ZciVBg(yTJxAZ`6i&KVJmyFy3fTcBg$V2vosfW3L?yCU$a-?XsHC$ie>NZ& za4iJ)F}UMruQ)!%A0_#rFAt#*PrQOX(dP$I(2;+>b3@RlKHZNCFzAjw zGZv$Ltp7itbDRVsV`*W&=!@rK{f^1H0>J{QFfXhV>WNc{!~&o%4np?g?nM6Xm9kr2l{Y73dCI;e&d7h z?FB55!j2#AL($LOva+&bAB!SDzYJDmWwJj;3G>2CIF;~%#snFJ4+7Q?M{??oU4Vrf z{Ev4ZoDgyB52e%rvW3N{&wK4w$fitOgBUBu8wI+PIyi~m*@pr>(f95+t=`*@KJ`7V zIO5CMnLoZKh1FgEzQDKa_zF;+5u)4@P)HU&qbs-F@hL&tuXb zb}RbyiTdO~CcRf65D)|*7K`B@sZ?si+O$CSu|&L>t4~V|IQH=S5B=O&5%b{-kWJ94 zQgO2<7p~1@JVxNuBlkhPA^M-vR6`pa9OQ5~JRXnF=QEj1i^YPmHZ_p_&`gXeM&%O| z6Y!Xe)8oVM_ec&n=F5X56WPUnxggQ7*T;vBqjzv45dNrc_J zrLVV#%jJR*i^U@AacXJ`V>t;lHNElw8nA^y?a*j6@LFA6C0~0P9UX0}rzO5}N7xmo zgnD5qNT>`v(35F}y`rx>vo;NP4F5DSAo4EI7|cwww0e>|E7-L$nN zHF|D##-W#$DF8?GB$^xdw#Mz?SKKKVG5+jqW|JxUrVF4L(*rOT)Fbq-AkSkmKX_tg zdD$T>3c#%_FZQ>j!q`1CGlRSPp9D1Qpli+x^Tbk#es~35b9T@jyU9lGIM$|w)2T-l zGWxinis%d(ZM>go|8{O}j$8lksHo!)&kv^t-?1yk8>RT6VAuq`j*7W+Ykzyw($bRi zSepfI(xPQnygA#tW20vqtd-8KjLP@am6vzs-aY%z9yI@p7l`NQ=E85?lK;|a5jPzV z#hCK+l>?3CV-lhBZ-s3-I5~$l-|YiflMUNcHEtT(<*b}tgUvw-NvBq$B3eJwD~8Ce zO{dlV^!BA-+7-Dk>8UH*iZX1Jj$%;&ZbH;7se4Qz?Ge_$Ecxlu&YbIc^=}BvZ(?NZ zGu3Z5H69dog{fq{?8ZQ#G}LY#Bif}xE;)`lkF|N>mW~9!g1ey9;Zd68A(Xq}?Wy0ba(kk43eYm09&)&$eu> z4ZmO@gPI=_cKy2ZjHSNPO1pm(p~Q z?1P;0hsJnSwzpuZ|AxiltWi*Lb6@hsAMHSZ&#h%3B-GaaE9LRO=&hTkSzssVPIG$NlfSb1Jh`J{RvbIk)ZmA62IaGL! zqUnyN)NA?*Zfr09OwgAD<=I;J0YMNVLI^{wUZ>G2WvWrOR>60?45?FIL<3w=<#Lc z>|<5FFi~}ooq372Y74vMUPjqVQUSwxEULnd5WUk=mT?(tR65A2dW&84Ii_@%07*qoM6N<$f}#xs761SM literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/at.png b/lib/src/assets/flags/at.png new file mode 100644 index 0000000000000000000000000000000000000000..05dbd1d6fe2d44492f042ef097ee7c763842c3b9 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MZ#0(_GRXsd`6iA|jgi_xk|>i~j%s0s@Q!1B@mnoGB@uR8+Bke#F?=?cd+<{r&z436K9j zKmWhK3=EJyKBrJnuWD+$4Gob729Esv{wgY-2ndh!^ZICLx)>Oisj1jiRkCMiy0Nj` zv$Nd4zv9!=>o+%~e}Bb*fW?M}$cc%`i;K#Qjmw*x(mFb&JUpfk50bgL-@Lrxy}jYS zzTrkjtIyBrBO{yD)$G^T?Nd{+@bLKLO@4U)YR*bkIbB$(sp*i+1c&c z+3wuj?{{~>;NbCkdcx}J^?Q56@$vacNUZeL-1PMN_0`*beZ=fnf|`NJ3FTT1O)#D1y)wFT3WRKKtTUsVEFNLK>L4JRB`#4Z$rekJiW*jp!Gcz;u{@txTU0u&v7T@IiVcM%m zX{tz%tZ(e1Uy=83i_U*k(kc_nfZh<0zQfuW{9-acmPjL zn=xV&ju=-yHM5Nn$;kKYB@dzfgNQEW>tfq=m_jzh~5TS?p7=TdFHvRI_u@z+9<>mh#J-?Pc(=0Y|Dw))V8H6Jm6nb`zH<~jp zBV_Rqa4xDBAUwgI!X`{yvG3EB_^(F1_$^R*@LmDJ6D(rF=#^dQs?-VB?(Izr%;0%~ zMa-DT0Llp8;)LGHAS}TnJd-!d4rmzLUuI!5vILLt451y_QEh3*vjmTD%u{OE&yw@H z6@>gnx}Lq5CMQJ^@rtXfi=`uBO$$p$lz{<7E+Rholxq!;s|#|GbQbC9$^DduY$;uG zsDSFYSh`UfV&99QDxhizRd#6z=^a6?5mn~kJ;>#eIQT%VhFn^0KoX)yeaPp#u3H9F z)jAT0xMOu*0Pxnu+!3p5X(^eRDrphgjGgfN(Ln_2y)Za9s0txxFggmK2;%Gm`kW%j zU4M*_J^qAsL#b~E+UpeoWcYZNI_)F^z3S+ELWEXAZnTaF+ku~WDCr`a^ T^Oj(f00000NkvXXu0mjfMY309 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/aw.png b/lib/src/assets/flags/aw.png new file mode 100644 index 0000000000000000000000000000000000000000..efe03a96c8bdf29ddac0eaef1d1fa8e79d1a8230 GIT binary patch literal 658 zcmV;D0&V??P)0{{R3U6oMi00048P)t-sL5bZ# ziQUW4>4dWAPmL%-F}we%iKka-n6^k+d^L4j-_#@=0uC$-^|?75H#IQ zXs5X0Z>HtkkEPQWI@`?NrnuqWPifnpv}T~>V4UNSwdU5k&(jq++Cg5!#^QXe=TMU1 zYoq0#xZ~By-rA?U-(-E%9Y5MRSKWM-+r7}j!QP3n=31HJLW$kP>OO;@X$3-c@hd zGEv@ah1##g)z0FVw&c0T=h({K+@iPOV0hOkN!mSH-+7SSy3NbQ-j1{7W1i!bv*gUf z+}yIp;BSZ4BShRoU)_qJ-^kgyyxf1S=24U2SeN04u;$ji(%ea9zQ*KpsOCqF-lMnS z-coGaqPJw9<87qn+>)u(89dm^-r&yO-cV|!xZ$$8-rPiC+>xhlrR8|4=H7ys-_71a zirr0+-{j8Sv%B8L&FF!z=ZdF~`PLSDp`Z8F8OFd)1+xCD00001bW%=J)WKNJs{jB1 zSzuQQDdN7I zh~#tM=9eQS07p4_t{7nLt0z7VBwmpOfWmN9@ci|q+&8Z@@hz})A?3iF=B3rmg48ml zyBR}BBV)>&amR^sqKs^~_E1Rv!YM2v7*fA}M}olKU4|H9h#`g;@+Xi`uMfoTc>UqB scb8_N0UyZqpBXM^OV|)Y4EcTC0xjVh6D44AoB#j-07*qoM6N<$f-v-JSpWb4 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ax.png b/lib/src/assets/flags/ax.png new file mode 100644 index 0000000000000000000000000000000000000000..c3df4adf8d27dee623dd9704b13774a9188b3f2d GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MV!3-n?Vn03xQmz3$A+8L;OBq6z@I}qxi=KUS zliJaZswcX&PIPIWvo$zpV*r%pi=4wBHCrxml2&?`c6#R}0h6Z*@-OqH-nEH*oGAEt z4&VQC3@i4ZKL|9Ct0c%Tc=MKR+h4qV`|iijZ8CZ1fTHD|E{-7;x87d!bP0l+XkKFoAJh literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/az.png b/lib/src/assets/flags/az.png new file mode 100644 index 0000000000000000000000000000000000000000..5bc4a0f6140c23c84cd922a1294602c756255513 GIT binary patch literal 451 zcmV;!0X+VRP)IqfVw@m*>4gN*i%m-Kps@JChcD?9Xpi~a2F|NsB~^7H%C*ZRZA@mXc=FhBXc z!Tsmx^J;eOEIadQb@O(A_^`J6zQgV{MD8|4@l|5-V{h&;K=qE6`ohNUH%9lMr}A8A z{q64ZX>|33jq+u2?Jhq5`uhIy^7yK;{p#%PFFx->QSLKB^LBvy&C&LcnD0bV^L2pt zpQiF~h2fYdcJkXc zs{L=PzM~GR_i~D2k#e>KO4A#0k43O0uGA!mjOt=!OYcw(Yp(A)XHeVI&Aq zoRo&7K$fqL#fcD=f}8?D&VJ-)=TRBR1rW0H<<<4g?cM#+k%vb-MFQ&?z{~5=kvG6* z=l74#1@iS>D)O^Llof3TR9VN&)$jz*;o tB%69;uc;qb5I3oy&Le~nLI@#*%m8nzs6n(1ed_=K002ovPDHLkV1llA^MU{X literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ba.png b/lib/src/assets/flags/ba.png new file mode 100644 index 0000000000000000000000000000000000000000..09cec0d51a9dd0c7ce0792501fc6353524ea5c51 GIT binary patch literal 741 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!3-qlzV7Q`U|%_e%;QyhfhDdaP9S-haVn1`Sj<{KVH3A z?3yzKjpm%V@FKVI(6g6cU%vU~p0JrqXQp?`mWI>f*~YmtQG4ELL`0a`(~4_UUJt z)uwT3&*+(Re(I9T)0bYEzvg;$(eC)tJ@>Z>Wz`*&vRshYbhxPXNO9ZI`f{&^iKm(- zpO&^-pyskv!)@84XP-6QmT9>!-S$>uND7JGyMDa-z;eL)!Xl!Vm2g}?@g-M zmr}W3!J;W4DR#ly8;4FkQ?y^ac*D(E2k-j7m7#WAEJZtFGIO)-HyEElgdryc7* z!;_Ylw(Rfw!`n@_91{GtAd6YuB00{{R3U6oMi0003^P)t-s049K# zhDqA5GXMYp|Hmf$#U}p7CjG@GwvHS3!6hIW1tJ>-CLRWzdl!IY6UCYx)~6sJ7zGp% z0~HVhfn^i7j~j4T5qn?~e`6D@h8k^E5LQDC1_c52za?5m4NE%<1q1=*vm)uXBPt;V z_P`|#3IhAYB@zw;h-ws+a~5n=5E>K&SVavS76e;I4m2qUhiMcoBL|6V6hAQuzLXrl zl^np99l@6!!rA>jyc`B6lU@OmpEA1;7&pE5+sz~)a&QkCJS@MCx+ zB?IvlpsaH7voLxtH#MQ@9l}@e*H($Rz`IW50B}VmV)sI$6B&bETPY&nA>;TFYY_g3 zS|pr>H9xWn**?XH6d>nEN>C8hhzqlRDsOUhZ0a`U^ zeFpfV1xXa+^V?Pvngd&N@nS*?BAu_W+)KnD2AQc=hjbtT8N?t4F^ECLAb0W;^bZ2V V?7wxvmgoQg002ovPDHLkV1knQE=~Xd literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bd.png b/lib/src/assets/flags/bd.png new file mode 100644 index 0000000000000000000000000000000000000000..c24170cc7abda0f15f07f993ffc9b6bda686b3af GIT binary patch literal 367 zcmV-#0g(QQP)EkaLKO5QL+PF6|+X-;}d zND639q(4TbKSdT~O`|_W0cuWoOGq7aSh)ZI0NhDLK~#7F?bn5Eg)s~S;0xZ*n9}}> zR$Oi(+0UYU1BBs>uIsw*oDVT&GN%~4!y^pi#80MifVO#A`OO+;sM;p}Vn3kgy!eOZ zgp#}PPvwS+^NIf`Cp29A*8&9_D-MXwJ1h1XQVXjBgq~Mctpj96HW(q|CN`KHBs`mV zNCY+skcey&A(7Z5K_atBh6Ed#bYikxwi|DMgzYb*{j*~KK$<-D804Rp{r77hBy1y* zO}N8Z_>Y(K@qzp0hLUsPAHpm2Y~!VDxCl>UM^asfUeu9^zmoBQ;C9CiFM&F-zH zB~W<9G@V}$oW3ox2XZ$n#ODHqSWANZg8%*c@#cz%*fegSfQhGzV@L&KQi=m}Pge$$ z6VnSVC&ss@4S9ibObWl3n>DX*mUj&lfuSkuC+!qjXlcCmF2|lKpc)2GS3j3^P6xqq&YzIKxkcg08R=(dq~4yB zczaIry|(Uqecks4x*rU5J{aqKu+;uwrTyWY#E0_|A6+#+x@mrnR{NZw_Bl!QbF$i( z^AcYxmA_sP|5l;=eS-Y=iSj>Y%Kcm?{d2wa&kfSQk4pSLCjR?`#P5?5zfXz(J|*${ zwD|8c;(vhXtk|D(KqUU>qL}7>8*iYmnM#8Eg0K8gSh$@R$ouT+;uunK>+J#v{`ASXOa?Pa)d*< z$KVi%*tGWIm4+|Bq$YfvA-7ULytL?v@DBxdw*wtgD{nT$D!W5Si`!Z`0;{ddss^0q^}-}ULw{BQorv(?pEBPD8G;!Gz+RhO9E z9zGWoBgHEhIPY;~xU0{=$}d^Os!%Rj#Uh~UY;<6+KSw>6N3derOVfRGh4NFio_y1M v(0A~;w35o3n>)3f8f1>a-C1PU(Rc0qZ$r6x7hf#_dY{45)z4*}Q$iB}GFI~A literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bg.png b/lib/src/assets/flags/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..ab3eb4f1513c2f1a540bb545ae5eaf358504de28 GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z)#0(_g27ZqPQk(%kA+G=b|7Vz%cTG*msn@|6 zC@ACU;uuoFn9R@^Xu#!E*eIxKthJd-T*A|6u@Qsw*-tX6nLU4i>KHs-{an^LB{Ts5 DH%1%t literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bh.png b/lib/src/assets/flags/bh.png new file mode 100644 index 0000000000000000000000000000000000000000..62011b81f752bddc5c34704caaf14eff416a93f2 GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z)!3-pqKYafONaY0hgt-3y|Nq~w-|si=yc3dq zPFUldpxVzT&z^TozM|{!|L@%RMiq_51bPmy_pQGxPX-{LF*QvI|oBe?ESC zJ$Km+hrri!mR`3H_iy?Hrl_El5&k9!W?i_7`>`02BbN$)r9xD%W- z*M)64(B3*v7srqa#iX+bg~N`tOJGrSIS46@-qy^O%(O?D?tgOSOkW-`YJ~R$71T l!q>X64cxnNp|FhW3^UG0OJt;Jx=VTtnv<{`>s?{QbTlC@Q%{|Nj2R?aoBOTam|(lERGY`0Up_O>oeH^Tx|X z!d%={WR<{;m_{y{MlPD(rkmcVo!_aR)uNu(qMzTZqSmFN)~2K0tfk(qso1Nj*{rGK zv#H~>t}ZICFDbesDY_&mN5fvg>&U|B$HN*X!x|^U=*VTwdB*F_#_Y|;?9RvQ%*X7` zX3crX6(`6RC&=y3XU%%a7ADE-&dKc0$?ed|?$B+0LCfyZ%kI+65hl$MC(RNj%@QZg z@6&C5LCz8ioG(I7N$fkM_fOV&C|);dhqJ4`9LL~_xC*FI0#^4;6> z-`rDTbFpl6uxj1(;vcm;cd~EZ^y1$1M1u;q~R?_2%RC=XkPk zdUHMJ_v-1Co#~dJ>Ga>-g<^X*lfp?tE!Ce1c8w`R;s#P4BX}e`PuI z!pMMSIDm6PfOSOl$jyM5VDftX-{oo4v``T70&`seBT=<53E>-zrt`|9ia{riGm zG=g6={PFUFo@9ceX@a9@guQ-*y?=>TGKp6*EV@RHP%-}f{f|#DkJXrv)tQmSjYO2n z8~^|Ufk{L`RCr#k*W<4wQ4q%AQ)h^4+t%8)ZQHhO+qP}~ZQGeiZ{6+5-8X&f{JvG@ z!<#%klk_NxRdX&`8*c6S8j7XJ?)hPDvK2>OlAR*1V|#5Z-#y}Zgv|^|aq27|Y-U1= zJEiJ-l<>)BQYo&a`(~w7r$z#10x6orCik>?=GoI&yiKHFAmUf>*3_=rvP6#*xdS zBk!kKBXxu9k%4vA>G=>n7A7fKU;C6sH!6SjT{mlI@Ba44fL^<%uj%)zDteUmtQSn| z*>aKowr%+n;^^`G?R>QB(0Zu_)V!ngpL1@KND7C{uoRBXWKy-%LbVPvfz+*y86m#7 zP{yW!)2x+JPY-CVQzI1D+Z|f#gU_HDma0CzI`+by?R??Rj=gXvpQ#3BSZaL>e;sc4 zwA}`1hNU=fnm@m&tgI;CpXSvZGQ(0hY=)(9*bGbIuo;$;n_(%r8J3cpVJW#8kTPb5 trQ~J`OUca?mXez(EG0KnP)cqV`~xfe y-FJk}z002ovPDHLkV1kM5&bj~q literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bj.png b/lib/src/assets/flags/bj.png new file mode 100644 index 0000000000000000000000000000000000000000..83c9474f9792a1051bc3705d2190f33881baf97a GIT binary patch literal 169 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 M07*qoM6N<$f*VJ9761SM literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bm.png b/lib/src/assets/flags/bm.png new file mode 100644 index 0000000000000000000000000000000000000000..5e87c6af2d144f6b3233ec63010011172c225e98 GIT binary patch literal 2009 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 Hu0mjfKUkQn literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bo.png b/lib/src/assets/flags/bo.png new file mode 100644 index 0000000000000000000000000000000000000000..17d56dc66f7adfc1c81e561a7c4db9a9a91629a6 GIT binary patch literal 1412 zcmV-~1$+95P)##cf=Cb{K_rNfAQD7K z5D6kAi16I2w`{I~;(`-#7ORf#2-@@WZJ!HH9IFK#hfCDqS)X4W&hYoXyD!V3xj@b# z=abg(n*$+n+w%8T^)~s&?k)*(zLaVqTlO#H^x@l3Ek1>9M<36hTzU9m{Cvy(N!Rbd z?&IUM+JOW)m#l?ftzW=rKev!8esu-k`SR!4wtj}6Y83hsKlz1;Wi9*b|&%gXD;%+AvH zeqtZOclG_Kb<*_AJRkF`9hm)TCO_4}{oOdGPTb)4<8<9bg8V- z;|T+It8#h9=Uu1DOnD=Gt^ROcwdrlVV#C|{Nc?O-qV zPZ)0`;~$Yj)|qI>4xR()9!uAV#v9YTVed_ua_93p-bngDlbydvvF+C>!u>HX=dDCu zH?QA!V}dbFVK^Z>qDkc~osP@J&f_BIv>g1F!khF6SHw)#0+QTnGPcZwE%JPSkT2e* zfa5EkAI|U?ig+p}POoCJ{v-1Jn)qjFoRahVaY>Lfl#QSQ=#s+C8XO07Y6#VsV(sKY zW{gXJx2`*BH-Gi4eMPGAAhv0^yWVWm05 zf-r=1f%~k!HBY_neQ42Qe`SiM@>!G$Sz`_`n(bg33IG*YbX|g+F*k28kpc&zg8`*o zXYH^2Jzr*%pU0B+@b=`Ydy2Swt2d<|% zuyu?p<`q~q5z$-d(6$h))%4!Jj`FPpIUDj5ZDwxbF+LR0Ngz2Hk{gUzbF*2xOBxd> z09MTzChmWV%YWEUVZhLJ^%(Eg4Q7k}@5gbLNDx1;EM6Tkb2`P)c=Pwa71u2T(46#1 z(gth5FBpdA$1GV}<4=mmLl&)y@O;aqKt6J~$UbuLp0R#n#&sA$TyWYj<9+RDPsGJS zL=Hl3421-dAVPvj5FtS%h>#!>L`V=JK_rNfAQD7K5D6kAhy)Q5L`aZJz;6LqUmMl# S@ic+}000030VMn=AJH&As)xyo;GA;P!Kq>VRHkkP68u$ z#DV=S*Dw5>Wg8ixm$os&>-6DIhTTVlqWGruM(RwvbclD^gQOG9m&Mb7Mlg7~`njxg HN@xNABD^|( literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/br.png b/lib/src/assets/flags/br.png new file mode 100644 index 0000000000000000000000000000000000000000..8b18eb2c5ee4dff8f9d320133435bbc7c15ca152 GIT binary patch literal 2009 zcmV;~2PXK5P)0+NagoZrB zl7_`u&n0R1w8>rR7rQBZd^SmkhINOQMw>^MEe9QrVwSB~5^YYy`oBKTcw~Q!h}l%-dm%K1KVI4qa z@Ug#g0hb||5YvhjtVK-o@Y0o+IeB}zPpmXsX^qnp8qa(yrm=>j@D)0g*km&N5iy5!OHNeBc;KWYAi;^r0uegWHsa;h2Qu7Fb$rqvHDcWJ~hi6!is0f5KrQg-I|K*;R__7r=}e4NE4{$~9N@9C>7b+kp!y z3cSefF9>G97??B@VOhoNwX`S@hLWvQ4?guhH7;D9M`HaVQ**Nd44Xl)<})ld6s@|{ z$0LlSyrT15@3~(WhQT}-IsLF+OVJ$akl}7F5hcK}NfHrHa2Je(snZ5)$^RRb+XMJTK|BH8$ZBUk7P}Yw=@n1Q_;h*?Q2i@%bLtRQB>OrGXxGj3+XGQDwjRUGdt_@;%ZAiXEy$JC6?8Rc%S` zFSvU3YT0OOe0BMbjQSs3k{*8E?{;>Q+IHM|;m+mL7?=&?rwGnWaChoJQS*`B(DszF{mp>o-?XFUNFN$G!{zeKr<#U_ zJrmMi{5EQ#iA#P(4|iU+&QAzr5?p{IlL$*H(#n31+L>MnK{Es)jFewIQl9-PLig36 z`=0*aQVTa3U3&-(e8fNT6*_paa@YkGhmM}kAFJClQk6ASrkn6-@9|N;s@R}y#X7G9 za)G7!>^Fj11xM`msKcp=hh-M0U*D`Ks6j+7f$)c&QNPm06AkW?(6ZHkJ@`+bbk^RA z>haFX1Faid69-R@yVgc#ghHByaORmW z!xao1(coVTO7jcu@i2- zkgQD+*0N|b7EzuOPDtYk3F{}0AP0DMG@5}wKa%20^fsm|Si_Kgo3Km?Z0*lZK zll&OszF1=JCJ-!Q)EmDr`$i7psYK+_GknnE{f)vuhR-KyPrw3?^-uT({-&gL?YRf* zAO6Gs=wCKZWVoTia|*{!A4Jp^+L~In%ZTyAe=H z_Ov&7=wP?Z!W|(P8i>Vs-eP}vr#n|i96EPwxIu@4d38-ZLI>(WDWW(ELFvt6#KSN6 zrS56w;=G)`7M*Ecj_f5IC zd-$D0yvB>Z_j;~i=={W|p}aGH#x75P8BRRZ`0MHWra&g`t)=?9LqT6>J;eWuG~RL% zUgF8R-CN5KHYq*sjRrL-KjyVPy&jDx)-YODp>^3T*wdxIp>VDPf6)8xg+ZuU%jc z9=f-F-TI?zlEE9ne5RFQ9*mr21q%x0LPbL-;@11iCj?oz7&QKKbTQWw70O!S6O@9EQPfdk><6}_DaAQm^8PFtO!l<+jk=a;fckLpCYR! z+i2F5?|;gnUcO&$=>c*4>PPn!X(?X=SNj{#yW1A%M6Ud{pZ)}r9 zqkz{o$@W%xOe>ljaIs(3bK*AOdJr3MMSg2H_GSyYwOf~MIEM}m{JxXop#coU@VR&# zC6hjmB9K1fNPHA+zK7>9(hjVgdq!^|25xRSXbC~quOu>%*`W7e?$9~bEkNwgI r%0*N(Eb5|R(XeP(G%Okx4U5(_W-h;oN;Urh00000NkvXXu0mjfcSPwd literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bs.png b/lib/src/assets/flags/bs.png new file mode 100644 index 0000000000000000000000000000000000000000..6bdc618b36a83ae3672adc19a46784dacc5d9a37 GIT binary patch literal 553 zcmV+^0@nSBP)uipr*H4XoXdk4}^#kd;pJHaKyQUSzV;=|2K@ztfIDRyqbFX0E_%YdXp< z1vTqn%W-^krm55t(Y6cDJ))Xy9H}%)8Sr(5= zS)qWaTg!O=eEax-5s5(~OGhOHjY5IaqjMFjPdzCs2h5pVFTiOaWl5<}UVC_3i*V0j zlqIEcgYvI#cA~5tFsM&;=U;s&ONv&jSvIFZsQX~bl2WCT?(F_n(Z0heOHI|v`f~?b zt7Y*tTt1hlq3i1^@s6YD=Kn000l(Nklq?TNz`2yFJ^v5hu#IUFW&) z(Y-bQhuQ;cx`BljJD?Wd?j;cr{LL2Hy#0VDb_1^eH~vl_p~VgWdhZ3?_#cANO@M@| zAnPVTLREA#AfYNkAl*O}A&_pXik%N6G%s=*+9TVgiV#S9^Z;g^v7K|heC@?Bo8H|X zRfIq~q6b1Ky8&GEZ5YYnuxf7GF}O8HK~2p>XU*YTr-~5BL2x1$As4#{T;;=18$N+o ze>;?ltC4LS3qD-~Au$`p*oo+>+4k$Zb+^N6`E+Yl5dyKR&VW;Q7lg?3$i}`!I@TLf z^Jv)8d|1+INKHebxAsBK5#eM|_Yp2(4^N%;actB)iY^JbNt0r$frFpd1l|EdoPf zj@~EKErI*#{m9*R0NQ*dXz$;J4)2=(FoihJUxcn(_YQ$<&dlg7NHnh| zM^lKRs*2zQ;fhPwL*g2tOSQ=79OPX&sH{jiuBk)HrXkN541M|_sAIl_Jn~BzOXotK zH4Ns0sj%L-2Kv0I&_B2r`uOiQ8NR|kq``L-HxGqE-nRl70ih5?>R`!SNUVTRekYXp zWXNUb!I4+Mljg!}`~z0iQaF{1pi2T&frGU24{)j1RO8d=w!TfDJWxZ?~lA?1lM4YXAIdCgb)aAI?2@!Ftv2l91TbK1@VSI2nHo}X4H33PNC41$z+&g zS=BXv7QDw!50W!EnZl9t*7dOOJ{0zQw?XXx7K00bl0Pd1q{wPG6Tk0yK)lE)=!hP& z@!U~$(8l*GDo+6Gu8mYMD5O=*Dk(Nd)Cfqh+DS3`^Z_tGya(<}mm>G%Suj3(81{?- z&}I&SXIsdw{394llF7q9fh;8 zsu-X%uG&LkG=BoQc?fe#x_%O}jZ+}C&V*k78q7p5IMQMtK(KFte9alqTl=A? z#n_4#t5*ku#8MMjO85k*)Ugu;QdKFG5ttIFQVyc`(M*h>QgTL- z*z4d^Wl*`5P^2_m$3`aA2wiRl7hi;Q(;OHY54HY%xV6`VjpC~gK(YTZa0b5vW6lV2 za4^XwCzeLauBWXlGDh!^jt8hHN;BriTU7{z67(^{m@^(4mrP{(7$>d zh9UIa{gModI6l^R+gYvtw4HGKL`tEz@iye z*`iWE5{yv@3aLh)F&KHjq9TC0pC2eEm=%jr*l}m?`amcV7a~VPmPBZBf>ty+XzeL2 zsiG9$gFTA1@=BzT>Gls2R2HG+{yBw&90 zK;Vpydk%y4$^9tYbqLz8`%efYA3F<{WkBMZ$Z0|1rL9-d&ksVjmN`;Ltz^zt6&ZXw z1u<3*sWC>MAuy%TRH~w=(kcN8dXj853quxBxcA6SIVS|-RG$x#Ptq!8&ZICTiaZpq z9BOhBoYoJKtGNnogHD9k_hpzv--lkg1g_)2b6o~2Q(XqFY8m+YXlWygj8sFnL2p5z zikl0jbqVKbL>V>2U6_M-*Y(3ey_s$bu5(1rOf#< z&oebhTn2o+iC_e|heBJ{2Ufi2&=AP_W>j4PJw6Ps7J)9T0iS80l^z_;Nj5D)A#xJ% z zD`G$*)6xFqp6rip^9OzMJGa8~9loV6)_LP@aGy8>o}VME-^LP%U<|L#pGxEM&4P8V z-vgfC$9RvO)-ywvQ*$c>uBjAKg3}?HN&Ub!j&9r?ZlVE3Lj=-~ucG~iJvRHrNGZ zox~b9=f~&4`iIx9LGIaeq5B~z|I}HVUgf^oqdxN?)XXSoI}QqK-GB?Y<*6`o+Av4};tLML0L^3GJ70u*Q7@G2TMgq={}Y*(EiKkuq50 zzlFZy7X}>wj8qGpY!Yf@74+vX=@~#eVuwPDk7iDh`IgeKFPK-6N@ydARyDz(e!|i< z8h^9LhOWaH{_*B>$xXYX^On89Hk}?h3F7$gp(`>{sT2#3)Q`|D{XYS)zlGhl#2{C# zfUssUjJiq`ZrlH#52P493RdfP$TUZo)7gr(Oz;ggv{Hld2tfh>cJ4M>PGj(3dzN~T z;(goJ+~w~&6m1V21J#EkOzsP1(H!JFk0}pbUC@@yf%E6#I8TuvP51$MY9M!2ARST4 z3!BdwPVLRGE8jw@VsUUHM98EeCgb4!TUC~VGL>(t3yyb+W$fn!0WdbldSb^aq4w+l z1AfIkHaBzYE8vM4l>VcmrKHCEd$;VGK=jD%&{8vDrANa`_J-H`3fg=n(2p(M>XTt4 zhQj41LtHu->E^~@-ys!m1sjtr{}n>nVkiv}rWi8K?-`6&uSTII3RhRb#hVBUbCkW} zmmRKx+HTklYF#C}rZKf2+kgT}QUB4o3yA=NL)mPUGo{Zi2_zV!7po6KuI?(>ss3<;-ymjV zR6#KZQ$kH9lk8T?q~Ij#k^3_ba&Ay^lC$X~N6|9S@yyu> z67J)tAs4S>Jp)xhRQ>RSKKM(TvrfPHbo^0^GUjVoOXr}VD{yL7BmcpjyKdQAs5%f< z^+hlm--pf5LvwR8`)!7yYjCm&0ANa?LudJ9J&J23Tp!D*<5I^+WsDMUq< z(`;&^9d_aN1JHTbLCAjgL~txeT{RExeMiH2=6n>c-|eq+(yj)CN?f=8E?8;<+Yi^8 z`#`On0RSvHdVX~xym~F%Nk78yt0nulad5_biH=*g{JRSM$#YrQ3XXyPdCt0@>iV;cH$&K3xxYT0gj-KZ5-INAK_-CBJ?h1CX9K1Eygx zb)@Q}(BqAehkpY09zXnbgg^p=QE@4>xo^V#_+AvR-)*P;tc#ko!may4U%en0^aVd@ zPPM=q@D@Oc|E9gdkQLY;`=Rr(0K)&o_(AUhKrmFKnU*X|$ln@FT|*#<9k7YL?VWG= zx2~sIQgASuZr%FIQf>-?kSg%_UswN=kZz!g&%7%(v4IR0_jGo2!V{=CyhsT%j4nQ3V*+a_WusK V_MOpb{Sg2F002ovPDHLkV1jFF%%uPT literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bv.png b/lib/src/assets/flags/bv.png new file mode 100644 index 0000000000000000000000000000000000000000..b7a42f40c043aba5f92f6d2e81501444c4be678f GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MW!3-q-@D=v~DVqSF5ZCwGy1%yX`1|bHmE#wc zoGMKNTE4cn0|kE{J^KIu|BE-CFlb~**pz+i?)kA|<=^Mef1khb<=c-F7w?H%mzI5* zeg|j{dr6RA@SRV;e*gRT%AKWp9Z;yi)5S5Qg7NLOMz#h6f%cF81+@kD{-10%t6;*4 zmtJo7j~leh-!QvenYOQHv)8LlN|8)ETN_}&M|^XQOHikxbLu|lJ@v}Psryd6KFyqR vrMj`9!KCWZ&Q|Ga$)9VF2nxVJZ9~rVEp@%#pC45N?PlbP0l+XkK&w+I; literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bw.png b/lib/src/assets/flags/bw.png new file mode 100644 index 0000000000000000000000000000000000000000..04446c453910d40a42fc6e40336924be0e7f5004 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MZ!VDy5r0#tQq$C1-LR?E%-3Bs&O~ zRDR#C3Juu4yW2rQz~g4-Ze8E)3)8+EH?l~3Pm3u#f1j0wsqu$wiP^Dt3<_$WfTl5c My85}Sb4q9e0Bd?fO8@`> literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/by.png b/lib/src/assets/flags/by.png new file mode 100644 index 0000000000000000000000000000000000000000..5633bdd413b1e08ee817d9ff342bfcd21bda206d GIT binary patch literal 1473 zcmV;y1wQ(TP)`tI-1QC!hf zU({Y`@59HsWiR74{&`w#+L{I6gvCc?S&rDa}hK=mDyYR-! z$~s2uxxLImP3o_-?6pxzr)#b zd-K!P^wie(;p5tKeDKD}`t9!Msjm6z>*A7`*JyFve1!Vz?AK{>%RETurmWUxZ|A42 z)@5$XJ4ek%Qq*5*_T1j)pr+b(e&LOj;EIv<-QU}GfByXZ@y^fHVQcZr&hEp<`RMBM z&Cu0iZ1T?1{POecxV-7Bu-9sIFUTcK>PCY^3Ku8HbcrdMfKR)+@S75AY z$umIo*VV_OWf-wr$(C?a>)K-&jS6z)<3X%TTURA`zxy z>jr@aYSv7u)iRYz1w`20Y+W_kPn7C49V)_~ph~OmRh25AR`n^BK;^!-@NF*mJNWK< zFCY2-pt3;mk}{$HW`&{!sG$69xscu0lOn_uuK^KW^a^9F@i)fU zd>Yv$@2nmFA6umYGCOwSE-v_!xLf`LQsGe`-LrG|MvE*^&Sv_~Os=IW?(Sr0Wy@ z|I{-_`2NUAmm`Ag5+O!+00000NkvXXu0mjf8?Ih% literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/bz.png b/lib/src/assets/flags/bz.png new file mode 100644 index 0000000000000000000000000000000000000000..0ea4c76e8d09d7822c83eb0957382217c53e5965 GIT binary patch literal 5777 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 P00000NkvXXu0mjfarSL| literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ca.png b/lib/src/assets/flags/ca.png new file mode 100644 index 0000000000000000000000000000000000000000..5c7340a66a7ce01c305ff922559c56d03316959d GIT binary patch literal 765 zcmVrZWX8~-TF6Gx)&(01eU=1P6A8UxdfJ) zVlixO2`mM@yujmu*NaR>U=`EiqT#l*B(MtV{vK|(;Z|3NhX;Z6XH86)3@0ZA*8jA* ziFh2j9H>+Znr1TO;q5Ib7VPe_*x9i5_Q1xbCPX6qo9Ai1w7>6cST{FN_fICB4NKRd zX-ekR)p&bzHY}>ORmr@q4UoHGD5PXQHs(lJ;V_<`O`979bJGTh?KCMjSg)_&>}E6# zKHt|?`TShT{Nlo>&t}ov3z}py`EhoJ6^Wps0f7KkS8;NJrzdQ08^ysOK0l3*No8db zXBLn$#g^e=<0P$UNL!jSfkFdhzk$Bv_Z1UtKO2 znwv2=h`BlJ?BMVaJw52^;y*m(NnT=sX)bnk*UL&x@UT)=eO0> z)wKuwujQ{af>wv6VI3NbD--c>CZ5X1O({4bT*LCD`!Z107wczY?>s}h=c4~`d{#<` zj(xp@+EFb8>+BeG9z--gGc#_QG+w0@LUcSO))w@FLMyA!$UB2yqcI8(rhkR zhXq4DNr_Gr+<<<=v4>6En8MqR3B~u7#yvad;I>pJkYX79r5YPmkQGCk>}(cTKUSGY zZJLGpfq1ArFMU;x)NU$jihJ*v+lWtT@CdjZ0PDCger^BOt67O5P3dfUSckO3%4x>? zj~T-yd2%Gqjlu0{yy2S)1Q8Z~sKhzZ5=2d*t&yn%B;O??>Ce^pw5-_z{DbXHZq|6Qc5Hy5l&kxZOuSblq9M%|K;W_i ztD>*h^r~Gw!~g3Acq9S+qfy#dJ*nStQvwlW?S#Sm-zvnQ5n$jmBu(k$CG~+#FK%29 zXWD=j-^DAe?F zzZY+7T1%|Tu#ODHX2vP6+CBq0&tZ1G$E$o*|EA0N zxsj^sr{bVzac+h!?qCBJ4B8K>M= zU#CI-#9E%QPKl7=>a-xX^jIXtA)l8arK@^$$AOG6=fwm9i(yD5@t!m|7LnIu%Onq% zp3Cubx(wUKKz_G=9!CTa->uIu86|&d2b!tyu+d`(W8&X+wyF*cemmxRz_DQ*lJ7&o zYuG)<{Ze!%3lkkQ!Zh~#N(*COEieYYl5cAz9u-Q~cW2nHXT6li$md3+cQ8`!NA`1A zIn>mj)x$zf^0Y|Pp0H~!SCfBZNoV9JH8H8CjTprqCzO?0Yo9*B1ZBr`Ek4aY;gL+!XHFPvdES%8F>9GP)>$=pW}#n{VS?H?+yhN=SDYSY^{GtI&BZdyN$j7s zH2$iE%bCCKTogx#|E`kR*1N?lHW=%!WnsA}li{asNu`|syP@4>XkVX~$+8vEIFMkS zYCXW)*U@3JEl^@OAC~>p!H)QSyp%_Y;e1$DlT!V^4&IMDod?0CVR_S~)(_H0g|<~# z-byqtc`DJI8I4Qg+mL5jDE=*<#=6-5s`!V3-n>o!f0l}0Zx&+Ua1Ui=>3q{DD{ENh z{Oe)$gM}Du>HvSB{}iUBVOt|w}k}v<#u$Y%k z9;Z?eF{G(sc`Y!6cSQFg3YHksluixHS7D>qQ1l+kv{ncB{pit5sq;}{XjtB*^DGTZ d!_u&{_5oVtWr>`_FAM+x002ovPDHLkV1g4|qvQYp literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/cd.png b/lib/src/assets/flags/cd.png new file mode 100644 index 0000000000000000000000000000000000000000..7e85a3dd8320a62f881f2b1a221a367eb08620db GIT binary patch literal 796 zcmV+%1LOROP)wZApwB?2!i+%hV2-L=pKsW1A+X|79rBfI@?Pg>d_?a(;@WK8}-l_#>7Uqz*G-~ z@mQX%Xr!LBzE{o1KLmjLIFrgbl*&7l$UKzCJ(b2jmBmMxy-1k6OPaY&nzvP*uMmas zTc4_2ps8MG|nr^0;aHf`Vr zvv!rUbC2YE!Yj@RqbBP@^B?$RLd(;xA>8S=at^3)yk)f_F4)h>_JGLg`d z)Gpir00EpyL_t(|UhUMyj^scPgy9LhnTMH~nVFe!nc@APV5>E=9lNcze5g##rT$ai z!uq6gm1gY?FnvucP8_Ykl)p=QY7>oP8JOOkd7h^&<$0AyqLNYpBhgtwsi2YmD_=?~ zcw_@Vg`|Q!6SMW(gMw(%&w~`7UnStqhjg3_J zND9Sz#H2V9+eJWM1}&vb=kH%WWf~Q`_+=~QCGYbnJ&!jPHr8vbrPAL3lmJc(DC@_F zZ!ZN?h5(Uy{MSvBgp_GH_Afwf7OZ|tL<$XUWdOgqv6+yO8f`2G=;p|wuoPPYi_1z8 z`4MbbREo8t*xPCps}_}Fb1)rT`{OwPxn4mj=3fF>h?uM87C^0_6#D>t?t4DBcYrlP zDK>%Br@wb%3Lj78q}bl-eiiF{>JXD+(K_E8EIwc-6`qEa#(yfj*OhWoPRdC+DJSKm zoRpJdic(BbiYZDlMJc8z#T2EOq7+k0{{R3U6oMi0002wP)t-s|IPsM zk`UP|EC4Wq0WpCBGJyjzfCn{x2sC~PHGK*;eG4~y4>@`gJb4&Cb{ar+A475`P?0E? zC@D#8D@$xEQc_sRtO%mV+;0RR90NL}4D00003bW%=J)ZqA??$Gc6008nyL_t(|+U?QFPC`Kt zh2h4&Tqco8K$+)B98o|;L==?r{oe<igC>56b;X zd`w;?(T_jzjB6{3oO#I9kwly)niYpcSxF>AH;2|~fAl1gPR)C$<2y+t@_mNfKSt7M zEsiwdsrf`(aAXNj6;VVHMHJb8jG@&=gTb5k(aFR|L*?!1BSId>~Bu9y6vcT+ga_7iag6S=R0Z&i;ud$pKbMFjx|v6k|XX*k9sUS>hWQ&^@n-Z zzwdd~Z=CA|G>x+)$S?TH)tB#n{QC9ppZTYx)j+{xo-U3d6>)pddKMjWU^w6~QKBQ~ zo67(HTIG7dS43X%n_MotfBHb<>m^^m*nikAC?kXue)?A^ExTX8orM5ABR~D@$&|h4 z<#8JYlKJ$l@ZKDsYscC7IPt)rQEcDrk4O5)7}bfsWNyp{`iQ~P)z4*}Q$iB}lP7k* literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ch.png b/lib/src/assets/flags/ch.png new file mode 100644 index 0000000000000000000000000000000000000000..031d1f7a54e4626fde6dd5014439e28bec512040 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^DImn>$A>+wD*FHb z|NAw|dzW6m43rJ^ba4!+V0?Ssm9Zs&f#KrW4I&4a5?D8|eOceMd-u6J6Uu-8QeLF~ zW%}nOH;;V!6vM&7^ipj`s-xqdS99+#hQhRi9*{zSyXWZD& zFfZYIJ;R@?tN;K1zw+KmAosCx)7BX{X56UiGD{yN+E0Dq!$* L^>bP0l+XkK3fDbM literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ck.png b/lib/src/assets/flags/ck.png new file mode 100644 index 0000000000000000000000000000000000000000..8c1d086d91f54905e83c49b7cc7b80a5b1a4d6ba GIT binary patch literal 1953 zcmV;S2VVGzP) z-xO})s^-uC;FVOJJ@*KNQd{5B2bWo1_1w|_E3bU$1eJa(SJr*6Qi4}RB1s(!4=uN} z_b+2Nv~_MdT>sDiM~{pdEM}PS z@C1?>3hRNT7S`S+%#hK;Vus1mtN8vU7BdtU`Ns?yJ*=64>A838pMBe2!?2hkqlYyU zT9cJ`iIrEehG8*7Mi1*sV*2|){8Mk*k?_^e>piy0`n8W;UV7iLt$VDsYYc%opSU0r zNhHtHZ`%EJAdVp{X2=3!SrfqujAvcR*7VbksKHVGBP*?Kd`cYx%I=zPT3p>BS13tw za=Egkrt{8urVat+Ha;bfth7SrAGSwMx}d1ElQfc;bEctfSjyuISSQDmv&IuMP-ofj zC{^u=V2MsQjVEPZo?j+cG_(%GEPc6?t;YL*2Ee#dsT7H2cP}&}k@&$#p@Fe=B-*n7Zp; z)W7~E0|f3_XaNO-4N+866Xrw;3@O<_At z(?}S`QN)Cq={Hh@A}LjExR-FmfddYG*Diyx#txt8+KFKKMc46#5*4}+&+XiHgx%0i ztuZGh=yzDAQ2prE*NvwR>p~-cAB?X%)kg=50Vc9op=C;hESui@BR~Z#2AI^}b#D zEfVn>lpnT7VYN%_lb)esdS!-5eOMYq2Cs_f{`MSzU!y9n%4;sJf%Hw#(S100m)@q#_S9Ow3@ZkL+@-CEs|w^{XEl*S8v_ z;;&{&!QeKdR1!u(i@)+vk&PK9=CIU5rqXM_jtnBxFW0?fu<8d@-aIo*%weg6?2A7y z&$-zkIk&78zyC|`JMA<}pAJU5%`;#ef!wk-6sOvC&ujwda z#rNJY-aE)eK}){&)Jj9J1tPhVN}r~64M-TfT6_2`dU25au8uJ(Rq z1r_b28gLpn=p{`@K^ygwV4ReaU)}~M0Yz&WEK2wSiJ3>y$NvPohE(3aSi?tW7^dAq zE3q$V?op)TNL=e+<&?Hwfe8^FR!&)~*2BU{7Zu)Po}pReFi81s*qhgSSlDk$&TYVP zJi1}k@gB_@#}damsN&hT?342vR{!Xu^{^nt)tzJjPA_cItoxo()J!a6(SsOWfVJ*O zBIUmJ3~;dSnYzs_hAHr^D6{JhC+Y&MFE@l?B`XxkP^HkMV@tpB#OiwLW^Z`e0H$CN zW<_Et_J6PetM#xx{5$BLMP@g@W`wDI&Ck9ha`jI>ST-^_>kG zX+11T4p?Wu@_`cx<8n$s9E+Kqp!j1t(*N;SyYnlz`}TpD@1mFrH5>@**r1M zW)9h8+xnIuQXTa!_gf)nby`q)(D7)Pj3;8Ei08i{cXEXOOZ zw2iTaR5qw!%nD0B4kNk`3m0kr+!sf}xV3%pJ^F_pK(#0{{R3U6oMi0002tP)t-s)hizP z;NG;c&m~BtDO9fjIi>+RrUE;s1U#n&J*Wmgs0Ti%2tTO_K&c8rsR}`=7D}!jQLrCT zu_IKnDOt5GT(&l2xj1FIJ7>E*XuCdXyh3cfMsL1Ka==b@!Bcs|S$@S@e#L4sVrnyE zft}NotlE~Y+MBW5p0nMawB4b$-l4bNqPO3xzT&UJ-OpH_v)38>hJjL@A&WY`tbDn^Y;7o_xtzx z{P_C){{H{||NsC0|2G7oP5=M^1$0tQQ`GqS`~K+C@CyI{0M1E7K~z}7?bWpo!$1%O zPzM|ahnbn3ILr+D{~r{~N|DZyti2+dY3?-5)9n@~Ih-c3+bleN=jx=0q|?%VdYB!HM)=t)MKIA7@6ywXGOuY?I?dl=$c3 zOW|h(0^~oDs!3{-gXKsI0RaL82oNAZfB*pk1PG8{5D|F;8^>2boWN)Y00000NkvXX Hu0mjfo@fR} literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/cm.png b/lib/src/assets/flags/cm.png new file mode 100644 index 0000000000000000000000000000000000000000..fa35a3261b94b2965094e96c0ef3feaba908e8d9 GIT binary patch literal 482 zcmV<80UiE{P)0{{R3U6oMi0002PP)t-ssU$Js zUmvg^E#YGy0C`@{5hnf77W~l`&Jrfh6DHCjCDSD&+C(Dda31J?9qEG{_O}@M#25R_ z7W~i_&JiZoH6zwGBiA=0*Ek~CK_b~gBHBVC&lM%wMIzl!A>B_Q;9MWzTp;9d9?uvi z<#HeAc^&6^9q4`?=zbp1870sfCF_YC>xvxjoEz_*8t|VR@t+#d8zuI+81}jt_PZGN zycqbw7x=*#(I6%I$rk&{7XW%*`_LBBA|=lhCE7$G+Cw5Ff$r@9000McQchE>tj5OF z)YM?8rAz<-0LMv0K~#8N?b)>s!!Q(v(G+i(%goHoegCH_L{YnWx*6L4TkOR;l5NR@ zrKBh+B`B5_C7ndYeL)El^=k+aAV7cs0RjZbpcMg9Z$yAhC;Z6ucqp?YI+4zfSVR^d zqE!peiVl%edQEB?10wfa`pPvGmhH-|KgK4{btc1cXp9z&2j32iChP6$21th!kyk_> z5iL29EYVJ{Y>6_Ah0{{R3U6oMi0003;P)t-s-zgCP z-T>Yz5Z);e>u?I*D-hy64(xde-!Ko~F%RG}58*lv;XMxGJPzJ05aK`%;z17NN)6>s z4dqY`=2r~oR}AM`4C-nM-zyN`FAwg72=I#s^`-^+y94^g0^cnV{K^9CcnRfE4CPV` z=2HyjRSe=j4(3=4;y(`HG!N%n4Ch@7=wJ)zVGHPD3+ZGF>17MyJPzt>3hHbM>uw6- zLJsV73G8+W<3SGNLJs6d4efgg?R*LCehKb=2=0Lh?t%#9Ne%CV2=9dm?}iBPi3s2| z5Aci!@s0=akq7dW2lAK(^O*+on+Efo2J@c=^q>Xwq6PG$1>{Q&^{55)ss;9}1op55 z_pb!^vIO_D1oyNA__qW2xC7)&4f?|Z;5QHZ#RB`t0{hAW?Rp9P%>w<=0sYef{@4Nj z*#Q3A0RP+o;W!UVR#+(j0004WQchFU!C20#0004ENkl|G80`sJlsTd0thON3!JGrzef9=Q>NmEy!O%vZ9f!lWSALC)qi~EIr~e zBclKY;?#()8V$AyJS!S8!tR4c#MkA%sV8q&0Lcor-A9fr;f_@fS2!+4h_DQBz^l_U zpH*B`h#$b>FGvtb)jr91sF*VV_`Wv%lsP`~0&LWdIFDgYE@Y^jy8}oM){Jm<;@xPZ zZn-HZUhbi2S0ICO-iBFawW-?W*eV-y0-yS!5|ZEok;xKrB@($rDa}=Y-%f;Rz(*n$ zc>?q*WFbm~V$% z7QPZC8@y{wG-Bgi6^Yn7MXyBmm6qK{(FpGaa;>6~2!QP|u}I(ED!MILxT9eU5a#$d t{}YKwL?RNAh(shJ5s64dB3vR?E;auiGSv1hze&cR-ZCM5vZBL)78&qol`;+07$eo5&!@I literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/cr.png b/lib/src/assets/flags/cr.png new file mode 100644 index 0000000000000000000000000000000000000000..d4a25c2768cb6b263748d23cd1240bb80a614233 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z)#0(_g27ZqPQk(%kA+8MC_5c6>KPRYmUEV*@ewP)dulo=9kT|B2VBzjKuJZlYPU}e~Rlrca%CLd%BgQu&X%Q~lo FCIIiBA2R>| literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/cu.png b/lib/src/assets/flags/cu.png new file mode 100644 index 0000000000000000000000000000000000000000..000b77367d4e0813812f4778b4412026027ae7dc GIT binary patch literal 793 zcmV+!1LpjRP)+dRy75vn6$5%0! z2ZP*`GQ1^iJXpC|1O1t(1C~WND{a|Wy=ygtxhMseMc5(dY^gmAy->*_%vKCi(3^;M zU|ED4QYO7rTGiE`g^plZgcCB>ff~K4Vj-iEMc5$kZm2yHWx=utccqLbDTPVtO+i_- zT#+{GsM@ZU!EBU8%M(lA?8B!;!uun#xbP~xW6{%>D2tZ+vc_>kCYEJnp)6V+YT2i* z++0~!j6za&RU8@f!mBAD1>&-_S$nk(HTCE4q-HV0Us+nl7p8KKpL?KY1M7fgnYZJOEJE_! z6<^4T={*v50d>Q1JnM#pq8AZgw=CF*a0>hfo;ilRE#{TU^Hx68cF5R%;LW>|(ueA{ z+@=n`ntgaX&q|uUxHLJH*%bZoNp$yN6?ys5U5Buply+BbQ~Q74yax-`Bb_hT&rhxV z5+=-{Hx=DwurQW8(nj#-xRCxy9_hQJZ{9<(MT47v<7dO0e<&-WRWD|8kK4+I;3NYN zEa;BHR^d??%^~a1NqEQ#^SWUtJiez3h8)3Q2u0+mgKB#?a)e>FiORn)%!V;Z4B!S} z0GB4(-BYDC9PLI~vlN5mbtj=6K-P9S7Yps7=moy$)JVM>UUY)5&<#?dxI%}}U(Q6t XS+E<^QQ;Wf00000NkvXXu0mjfy}5&? literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/cv.png b/lib/src/assets/flags/cv.png new file mode 100644 index 0000000000000000000000000000000000000000..1684576e5a52ea625368ce4ee214acc2c30676c2 GIT binary patch literal 1040 zcmV+r1n>KaP)$)YH_4y;*Y+qP|+?Xl5zuWj2#U~PNHw(Uu5Z{B_N7Gvi8Ld1O$r_=X! zK^`m3_C-3FJnzLP>sGGbaHE^l-E zn|yKed$9P^O0eeKfQ6q`!X+(^`z(>`?~t4X3ON^i`euE^&WtEn`HAH7B4q^twYg`;54*{cR$&h~^~BisduJ z4=+5`21&DH@WPXA5HmCGtTJL|#NmY}+DgtSebc89A6(z@)2Zl$Ny|6x<#m!-bVqmEK>S{k*2Bb$9g%s{U;jTBK ztGnNY=Wd3{l6>u>{dT>f{i9Y$gVv`N}BL`DV?b z5Fb?Umx;=KvN89gD!A>=o~YV43uU_Jol!>V?ggkK*U9z499hrSTnaf0+Qv-7s;>^s z%lhWMIw;clmgAm#b-UY-yFbwRX1(s9WJr$YwT+!lA!p0D)KNMoYu|50aCQ4zPdZ)b zM8~e_a2xjiUIYhz4`?1=vV8E!L!D7)UqH@bxUl)X$5}r_&#@D*_tzr&a0gl#{R z#KKRi@b@9%CeZN~q!kR*S?|H+4IOW#5JDm341^F0p^(jy1Nj?TP&^M|m(o}O0000< KMNUMnLSTYaNeUYP literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/cw.png b/lib/src/assets/flags/cw.png new file mode 100644 index 0000000000000000000000000000000000000000..aa7b8c8579e8b53992597bbfa4b9f24591ffa5ce GIT binary patch literal 633 zcmV-<0*3vGP)0{{R3U6oMi0003jP)t-s04sq1 z|Nj9jfCeyv3NwWL{r(U*hZH-B11*67D}O6YYzZ=h{{R0mRG9w${!3}4Pi?3A`}`|U zm4})5dafHmjZkf;RdT9bc&=V~u4#g_YJ;?KiMVo#xN?fQbd0%r zk-P*ifj(cJM`oikRhW8_y?&Iw4>yMzL5&A7g0;fhy~y6b$=}M;<<8dT(b?$K+v?QZ z>ebxp+28Ei;OyMu?ce0@;^*<>=<)0B_3ZEU?C|)8w z(4P@O{0vAe$ABca8IYsbHWZm#j!)%@3X|!C8@I{(VSs)L+$zxgBlwe}9mI2qK6eK89RR4D~xAh#)?O2LC_`B8VV@2*Obh37_z7 T8c#5400000NkvXXu0mjf!f{2h literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/cx.png b/lib/src/assets/flags/cx.png new file mode 100644 index 0000000000000000000000000000000000000000..826b2309bc3c3d150916e968439bef8955bad61a GIT binary patch literal 1549 zcmV+o2J-odP)SjN zt_ADS?c*2v{%f#DjiJ*GibL3u)d5z+K^C3BiJk&EtOkKBKaD+JOg-!?ki*hGvb(%Q zOF4C}lzKUkCx@kdWGk~7@VZn+eL9yXgr$9C-qCu%lH$7%JqaxBBOC7`o-C#%Sf(=i zl^~u3miCeT62{5Nb+&|_=_V4u(mJw%4u)k}jLa)Okt2eo0c8Ch#OZEAzp9IIXMQEG z{e?6UEDaztc#5Y>s3S#mS_%Upzt)R>6H=-4=5lJNBN;3WAiK|704%xO*5)t(G|Z_| zp}q>{9-Iv-b36~VC99_mPZ33PPs){WgZ??WmpsM%k4BVdEU|^ohPMC zejx8wK{nA1f!kNgy>R~Z)lSfSBqwpc8b`EcA?shi4QkDp&j;|QOO!FmfdS722rBYoJ;dDwSC{1ZQYtr%*_BV9 zD50Dq_5H|UH5y!T+jvO4DkcLtRXr&Ugn2PF+5oZ~lKGgWjv9^aqL*iak7@`*1ct(M2TCtU8kV;OFJF85!d6s`M>!kstRH zR_D-i=VVhZa}}4uGzQ0G6WRKx!Npn3*TMRcPBzSj1o5rIYLB^_&zvz}UcXxmZfeOOoCPQsB2Mbpm4NuL-Qb}=6p1w4g&#Z5&C0Pf>fQ^>EUuv?|4P9#;-~gWX7hqWvlh}nB zEKK>aVj7MNlW9R3>l4kr63EMfs3xp|Tn5(0Cr(`itW_IMU|wrJyk_z0GC2hWYpcnK zT@do9BCItzv{XUoORWdz2S3`9b630hLm==aiw=M9w8p`IV=aI1yFV5ez$F$U%*DE6ukcqGe=P#JP{CkzntHrw> za=MlmR)XajY-S28lftkY*Eyh+Z?&h!;t*(EH$jUxS~3|3csap5h=*k+&Gthjo(#{3?RHU#4YP>Tb%}VG$s+ z!y-UN0LzYy7?vFwIV|k%z=AeFWV*Uyn(;_MaQqJRB<_2)tjSRAA|r1^@s6YD=Kn000IfNkl{A$dk}e) z1c(3;2@nAy5+DLZBtQg+NPu{_9CjOQMwI|@KM4o4z6TLJHxINv`vi!)qz^fVnB86A zJL)S0&o2PwwdJr|^a8{Uu?b0Mrr^<#_ux17dwPZB5Le5pPlW2$dc++Xh=8f-2!odT z*g8q-u9n@bWk~uj1X}RC{4hpblPb%#k;w|h)ujlWmi{pq5o>F~ZqmR-5+F8%0;-#9 z5I8;K|3D0VAJN;}z#RVwPe_26<9)b$-;EboP0&2p3H9C0NWL%!;j5~^XV^!Nd4&JO z-=GgZgXc(q#2+2bnjh+WTaluUhE)>-Q|vv)7&xqEyiE2KBdppusP1g!Vsp`-YyRVZ zh9x-|FOUE+gkOH<;`t2w5WZu+LFnS*2wzhJ@kfRs`TQ&-otuutlj9M!rNzIJ^Ux3Y z`d6}~vs3YMNyy@2InAQCwqltJOHv@cPJp~j`k+%zgAp+K&)1zt2@r-6X90;j&`+kl z&zhQQ?(cx&$|9Iz?miVZLKYNu8jyrzBL&F+EABvF_>KGFu|*15P>2;3%yAD9v969& z^GC?SB5>F&0)#SzUF4#;-Pizn9gv81bz#-TgQDyf9X-J#fY8);HhCA2pqbeaFf}b_ zMNnQ}fuLF0Jq8Aiy-M+07jVp@06ZJY`y82g2M|_LKEpq8+hY5S_!RMn2Sagb z0lRsIP(F^(C8eOcy#a>M^E?4$8SEuMtY!qw&gnKF3CBl0(`#8_d2QJny0o+;ZBGJX zin)Wp8Cl$t8~EJ<6^qiW&hkwkGJTwn>;T0r66jztP zcl6gzff2R2*_#}@%IJiray*9!oRRsp7u|o-ABfr6A=Nq}azlN@?CJ!a-(gs_v2wTf zUEK%_o|o_cLe3`$nwgcSfC!wH;jwNy@zeyKughg?SBNKe>U-N@QG`Br9?m;a1j0*e zPLKf6>eR5=Yq6cIBq1pVl^SG0$38V+Fz7IC-e9;>N>vh;teJvqx6h^iuB;e4t%vvJ zkn6Y4qe0suIB;|`W-T58cgjEL0S+GDiuS#$Vf2)4^jPl#Vz!vDecvkFx_1da{&$e9 zNI-OK7DnonIIAzlPVb4}Fh3R;(uX7|;<5Me27va;5X);O=))(rW9^oC{4Det z-jq3u-h%kVX!r))MPgE{j80zE#dGH#JH4At8mlkvaE32D^1F?T*G`~nqwLsqV9j&A zfs5XvOF4cP7oP8f!{Oj(5Dq_skICrdRmG&vUEFs>GmM_v9dQZK^cd7>SpaJ`&%yd_ z3)oHL+O4yAQo|>9MArdzaq;SL^c>O<%{rCFrkzW0=l&J+9@d1PhZE=a5|99SQ*q(h zyoE&sVB?NO*s*^#0z)3L5Fk9*?KTzz&>OVOL4<*ITjz5`1GCx4a3#aVcP;K{mdEU0 zMojF46&q%7B+y{^)ki-%CNc^(9Z z`eNbA@o3qtJPbxX+#~_Q5k5O?iX|&O$Y~NFA^{>mL;^&Bhy;iL5eX0hA`&111dqf# a$NmB8go8Sy`vq740000}5+Z<5v7ETeN-RQigj3{bJ4YhA~p{bHVtb{W%><6AD@ zeg3+$=hyE)|Ns9tiCVq~Xe?VvkYDhXt1o~2`0cRmXcbW8g{O;SNX4zK=XZuW8!|9B zGJa#{aeK63;eRhq^Du+k2lmK5UoM=#=KbyYd27CY{rP(0RUVgFjUL7VnQTgDJ(fsz znmA8PQ@OexE~mmqK~-a|&0OLVo<@s}7@W_3l2Og<`2$qP;OXk;vd$@?2>_Rf B8F&By literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/dj.png b/lib/src/assets/flags/dj.png new file mode 100644 index 0000000000000000000000000000000000000000..64ab04e2c625e43b4a0a65a9b0898c092153035a GIT binary patch literal 1154 zcmV-|1bzF7P)1^@s6YD=Kn000C@NklHuQF8~JDKTD?f+E`ug`aRlJ?ew938e; zi<_;p6pDY*D+vJnQ3DHdy=cDPf@bSPzUY;Nqp0($7XfiXhr;vQp^cg>b0mmre-P{E`Zx znqN{ON7wwVspgkM$k8?b%q$N`h-6f_6b#<$Bq1`v7?4~WMrS!{eiCwY&A+Nhnwp=4 zaBM*xlhfQJE9f zMXn`+o;&O$ZR9_D0t1kwLFNno2*SsNVL=h=a}&)eVJ~%hYN|l9D|3Q zbiC01gNPU2h=F-IUNmniLckcj3m3z5(;YncvwvN61MCBbfTH=abIMZ6 z%2EC5TW2k!{K3cgk&!SA#?UQw6<%IF^pbcb;R0cb0&BNkXOvO@!!OWXE+mpnS03Kl z{T(h}`M@RfO2S3LHF3%*Wtf|_0vJQ0utaS5FQY52Soxr+V8siubm)9aAvN!PghUWE z6pSvNhMU$tB{Wp=LUbMF_dRl~h^ucr=C{^pMm$;HxE+sed0Rk;5(){Wr1Icly8Ryb z*Q`T0BMTLeKg<7zd-_bogF>$fAMg9^sEr~av5PuCHK}!V;21tX8vkw<8&><#=eU?S z6*oHM^utxF9y(@&NC;!7c9Z1HRP%5ipr?CrRr}Y4y-S!b*c@iRu%0LaiJJ?KgSR}-+2GA>iIIdm&sK}5= zh`|iZuU?6}H@qY|AQF=7$i%BVzZ4w|38@d6@kd&F(SeYVupYsX;)%F^&EulOAR#O3 zH{qd8Z;%MlLh?LCcz@4NBtWzfd(??mSv_&3*t&y+D29r0rdhaU?K2d*Xd#=;yYR%; z_b6=9LP~t)_Mjn{U5MWKln(h#=b z&$JE{mS`b@YH<=GaV<_la>du;B!t)EEwg&aP>Yk0Y30lH``3LMy=B$g61?d3KTk*) UAce&J8vp&9eCm7aeBqHK;6YrZd-e@B(Gj-R69`4=&|9%!^@M7IVdH_ngJyq mco|GlIgL(B7%T?smzljjy?Ni-ZFd>mVNVzyK7aX*-+%c<1&hJ@?n%R^1NK!Xw`BCf z7890yUUkPmJMz>YRz8v$tewZ=x0dotrW6|3tdYCT!QEx!@PKN{O#H2t6&Reouxx$N zm+Zp4kpf5Z7xtKyTDn5{ouNl-^%6}RXp8J^ zk@*=z3f9$b@9{z5M%P*uQ!p{RVC^y%f5|2!!_!chCkM#wabY^)j0E@4!ui6{pR3?^B7(62(e%#=hOSs$1p3Vo0FL;^jO8cPq!+kx& zVIIRWQ6JNFSvJ8pTVwm~34=1C!=}yYSYGLRgj>oEKDFWIE83rU#Zj?tz_a;uDgo}(LHouJ z3z;YKsb}*%eX>|w<-5kEdS&2rjnxO(>Knr~eHV8=duz%0%HHdoTw%4ZCoVph=UH`8 z{FTwQZR9B`!PD$*CIZ5+KXcG8lO&-7w&PJ6JdBITQ( z+`O;GizgZv9AXlmJo;EZeZoTDH>o`FHFwK3gCCsQawX~XkzU^!BCqUyC&&Awl|F9a zFdfyJZFeCWmQ6MxS{EGpu+M+8S3Moq41IW2-y2)>_(`X12*TEY6x!Cm!fCP$1BCxuXEOO?!N80Dvkbnk*In zpz56vl&*HujQH0q^Q|&Jn->4Banln*5;Q_Qk1NGLCM!cthNcXA%=&k-a=)4syRf*^ zhC7SDTv$~6=Y<8k3M-J2C9tcozqw?E>Qa-wWW@t=^i1Z-U}ewsJ%hzyF<1;1gT-Jm rSPT|}#b7a54Av%_kc6$34Gq?x!bzR@01(Nb00000NkvXXu0mjfbD?MX literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/do.png b/lib/src/assets/flags/do.png new file mode 100644 index 0000000000000000000000000000000000000000..16160a376319cf7000ed145626a6d74058d0293c GIT binary patch literal 700 zcmV;t0z>_YP)0{{R3U6oMi0005bP)t-sB};g( zz0Uvt|M0cD)iXu_En=&>%m4rX@3FYf5hg28e7VKc<>%?QyurD>!t?a>^1j2?IZL0W zs$*IdCSZiyfpNO=Nf;&}X*Mf>jlT0m# zI@ssYE{sK@$)=XOlX9_z`&@es3uH!@9OGntaKG|6`I4BaRhsTedjGnSzqht_w7LmM*X{&c#o@RlziqunK&@MoKQ*WJtmBl?!f0U|0 zkVyh}AYrF$@9F7+vV~=*a_O|X(?nI=vATttu|r>mp1r0HcN!IeGOxy~mqAK}T2(8H zLqm~N(8kBhs;tSXskOMQ9eNl(hdz)=O`~RQ;Lp*98zzn>FupS!t2ZN*EgqXV9o5h`(TB5@K_KeMUZqd z?p3rIagV#|Q%#?UC(TDV1BCpEP)0{{R3U6oMi0004%P)t-s|Ns9b zcu>+1H2?qq>W-hIA~VYpG)6`<(-%72M`Pk*dgE$<=!BOLTQlsMsqnGA@v^@2y~p&! z%=OFC_R!b&)!X{x=lt&R{rC9(`1$_%`fNBf%o8-m6g1EgGzniba5pq@HZ*xNG<-2M zhAlIeCp4HRG?^zfnaG-o<90Ae#~ zIWx`@G|><=|Nj0ETr<-aIT2ek)Eqw49Y56`K-C~Z)gnXIBSh9EM%E@q*CK3m&AToYO|;9GRyTyzy$GvZ}@;%0poS~TNpf#r3I z<#vncgO(UsGw6nx=!coz1Y>RWt0JtL>hw@2Iu!tGDp5ydzaKDN-}> zv%m4Qzw)}o^1H=0O*21AGxWsG^~%yfNi+4!(+6NP_tM$-)Y?ZzH22or_t)L|;pR+5 zH2UP|PD3;O^7Q@n_EteNS3opaKs5gP`~Lj>|NZ@3J~UlEGko(#y1Q@P-QC^Y-QC^2&)scrrUCkkQkmVg6jM$gd-f`2uC<#9ryW}BAemtViHf2arT@Ma*;9tqkBU`yd zk$x{Wau=aMblA4%IdLwT>J2NnNSG3ZPl>bufwj(QOyq+=Vo9gcp1g=69&%6#hVEF| z6W0+Il2Zgm#s2RyUI&qoR04TaH2xm3Cxa0%G8IF@VMj#D!H6x$5ntm5B9aeCIz=zP ztNv;vh{z0q=qa+^HtBj3ECds|ArLD?1T!HmT?7>=1*70c6&`wkHHXlU6hO3+A#qj% zO2g=O00&6}BtwD-9fYRU&iqQoc7n|ANjDf1A@rxKR`zto9kxAbpE`t|Fl_u4V&n1O zUHETd{PTqU$;keUcjK*LHM>xU}j{M1=pic<_vl*2v RRu2FG002ovPDHLkV1m*MsM!Dj literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ec.png b/lib/src/assets/flags/ec.png new file mode 100644 index 0000000000000000000000000000000000000000..96d84f7924abe82855cb370ede09ced6fc636784 GIT binary patch literal 2568 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 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/eg.png b/lib/src/assets/flags/eg.png new file mode 100644 index 0000000000000000000000000000000000000000..a5320a6b55059589c6ceecd350904b980cd8c440 GIT binary patch literal 1106 zcmV-Y1g-mtP)1^@s6YD=Kn000CTNkl| zqCu1f(I85LD4BfsLr(|uH1IeCi;$($iJwP@a%r7yzrTq~8rZ@xhoAWrHaDn2{!gvS z4(fAT=o!0^q%}vjFit14bU3jEqWl2O%5EgG{D(A1T;Gp(DN&|-{-X$DNLyumvqWO* zh|NLI(RiQY;wtI%#M?vadh{b1xOm2uM*GC#x zSoh6CVFn#}-b?f!eys*+r?gcKvm_3(hK{}sk7s)8XV`2PV3^we z8FBppHrq=Y*Jw8ll2nl>8}^Pgt}?a#bM~))pTfW?jGuZR09${5B?KEi`A%G15C1DR zhfAs)3K~Q*MAqQFBW_NU?>nBqlKJ1ANZOc#=-~erL81__&2&?DaSdZE66M3vg^TGO zy^z1_9lH?cS{TWM*FF}Otc zkhXJS$%+ukKolWqgW~8}jN1Z0Fmd{$6i3dcGPxxDpBRI8A*Kdtw{TJt0f{gOVtdHt zhUq%;Xd0!hcn>2d+#bTsAC1FI0)rvJr8+~}E-X8E#6*Ch(0?LPZh&TWFLQgo$M}ez z!>%CLHAZpp)Np@GL~w+dx`(utceu0x&LJXUZ^-wb5@HyE(vI($-Tf`%p;g~Ue&E!w znS;T5k4x%+*C6fU@uW!|kHcpB7(3-&^7$dUiW8)b67}j1>gDaYxJ0fvPChrt_-PMf zbG_ix5X5^&8|e)3NrQav@l2fgI8mmD#5IYNGKp)D$@XJ&{Um9FB&m>w`&b1IJL}1V zuT?@!yw^RXoq8uOXX3O6DDC=z#HWad#_UGK7UwVg(;(o|nCjjoNTx`=wx5hK96ld# zugwEqA5gWEOPkbY)*xbNR`=n><60HOSVW=_2m{VJOq9cuQ0zaIBrZ|tKPCK5m#j7l z7ddT)*A#Je7jbzPwdqxa&EBU(`F`rNn}}?I$<3e8D(?#SwOrCVR5A1suJ;M$y}#ko z77}H{zT#XXTy)ztNZKlaMBxsvPh*V9(lc>sm_eOF7A;!j=|Dn?kRUz*5(q3_EFOy| zq7w<=Q42hX(jZEMXb`1AG>Fn58boOj4WcxN(jXc{X%G#fG>8UK8bpIA4WcZt3bkPT Y0X6&J&4WR@TL1t607*qoM6N<$f=ago5C8xG literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/eh.png b/lib/src/assets/flags/eh.png new file mode 100644 index 0000000000000000000000000000000000000000..24bdb355d202c8f226865ef1f1569e6bed093da7 GIT binary patch literal 656 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!2~2#!(YB+U|d2TM}`#c=TI)q#vF`|th^u72?&)2?5=AdPRitzuwNM7)q$Zr_ASCBA{zXS=Pv z+qV8*s%^!b4bL0?Y;c*X^74dTmgnx0x4)++2B+1&vW?K*@Wbnp?A(8U_QaHCm-yT| zy1GT@?We8NuS(l!hpK-4^7G5?lxd&$1P3P}EB_#7}S>kH_z51)KUAM3PIbAN}N2_LU^OFbDm2LE+?@nF% zJ6%2Rg9+chH8JK-uiWgB-X4E7!y}vdWa7lCuH}55?R}BTi}uyz_jmW-pL>^uY4W8v zT&L%TN;93FYv=qV{@sW4w{u!ePHH@NnzdSPTSlH)j#1(BFNW#i8H%eCbl=`saNy86 z%V}j-Jwy&w#cVru;G*s(d#i-G>q0jloANFG7o+#qs)nyie5N`smUzV|wlci9h&_uz oXT|aEhN=#1=)@+zn6Co%*5QXs3}laU15+AmdKI;Vst0OOW8NB{r; literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/er.png b/lib/src/assets/flags/er.png new file mode 100644 index 0000000000000000000000000000000000000000..bd47590b939cac2179799dfa639e52cbf95a7daa GIT binary patch literal 1406 zcmV-^1%djBP)kBsbe=P1PGxAa}`kX5BS}^;g zDgVSK`jjg3STF7@H1bU`^j$CXWH0`}C-Fft>=!oeA2jhuG5^LU{j(?dhAZ+*G4MGu z?=ds|uqgk>Ci|o*`=BZQz9#J>H0lO6>kKyhttsswHSQ)f|H3BywkT*YLNfJcF7ZV&{kJIoyeIgFEb>t>{k16XE;IIb zE&jSE>kl^kuPE#oHu{<>?IJYzfh_xe{=p~tk1OsaH2a<^_jxVwH#7diC-;6V>ku~ijw|X2H}-Wc{=O&t zswn@%Cii?S_kJz?v?uaSF#N43@kufBSup*wDE_@C`j;!~4mR~_F77Qe{H!VK5;pT( zFa5YD?H)Di1~>9fF!gIL>IFCbu_*2*H2R$??=&*+H8b{hE$%2Z?khC-i7WYyE9@9G z>=ZTkdM*CBC;5yl|HUT!t|;#|Gwv!g^=B^mkSo;`OsY0@fLEVYc**P)HSj(%{HrMT zZ!STJ-S~to`kN~M#V7AKGwmET^k6UVGc)vIFaEzL`I0O9qAK~3D(xgR_H-`rI5O=W zHS8HR>k2mer77zPHv6F}`HL&`V=n9#HSvLTMhhBzVsi6bU|3yCA9W@K(*X+>mh z^EXcWq;?hv|r`o1MFdryGvfrX9P!$(B)_{mdTd-nW=*k7kcE?$3W z{fd41*Kgjk>v!)zeEg)l^jYxtRw7^Cef{R+%j%?`|HW4Uf$Sp%xw~Bq7ThBx67oqO z`YFs1XT!-V;>`o=aH7cbQPC0COvM&fi8wuviPfDlL|nWBB>-R9VIq)pBbk+UNQtDR zrln`Fmz8<`UKWsjF^8Sz0!U$@9a18;v3Y#?@;?G^?BAZwB|fQu1rN=T0x2lOjUpDs z&w-LsGW%@}%Ybqonjr;JQ3+J>st&8EeNy+Wo?m1%pz-1vo?0OV;-Pa*b@{E|WuNwL zqGFcsZDVV1Sg_IzDUiTs|LhiC_0$R+Pl;+{7jf+!p>WiUbar+3C=g0TD0+z~=X#$h zV)Xq3{G)h8U&EVl&A^~x6iA;faL&pQ9YY5$4gYcM1&lbhYX(%v(5N2vpNWcXV-VXy z=690E*l{~>v1nW~ph70TO-@bw7(#bF8mLR3NjSwea~274*%_Jv6+#ZKB~u41iRN^T zNzX6Ab$)?p(YX=lLffx5x@vJxUPQ$1hXC7$YY=3R5tLYeM|sQA$%4;0r<2@v{g$qm$D7O%}g`!HwYE) zJOx~J8|}44sQ^OLop!|lBZSYX+eNi+o&zfp4K52-qJR=nP2C<)wkQt#BXVhffBWW+ zIG{p=_COpF1UMoa;D~I1BeDUG$Obqf8{mj+fFrU2j>rZ$!U4(i3%l#>S`#IL00000 M07*qoM6N<$f{>J*I{*Lx literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/es.png b/lib/src/assets/flags/es.png new file mode 100644 index 0000000000000000000000000000000000000000..23e714120a9a931537ef4fb2fd9deda83f4a68ae GIT binary patch literal 1787 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 v3%5ht00000NkvXXu0mjf&(nj- literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/fi.png b/lib/src/assets/flags/fi.png new file mode 100644 index 0000000000000000000000000000000000000000..7c1f9087f8bfa1114c1b8c2a9a47e1bcb6aa2871 GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z?!VDx=`d*9xQgQ)4A+G=b|F=z@FXrCOVA>$% z*{dEhSwCue&yr&oZ@&OanG18i0IFmz3Gxem{_}6Z%4_R@Tn|qd#}JR>$q(jqvZP5k zJ3jT9lfZO%#k4@(#Zhis1y;K1@NzCWv}MQAhb)~ur;e#GEe6T7b&45%I-Rl5WL0X& f=@nwLG8q|MJM@KXEiUQ+&1CR&^>bP0l+XkK4$wpW literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/fj.png b/lib/src/assets/flags/fj.png new file mode 100644 index 0000000000000000000000000000000000000000..6d9a4e18fd280da5b6ec5f208a0c4f1801ad900c GIT binary patch literal 1821 zcmV+&2jcjNP)( zosRKavoqfw%=GE6UHS5{zlNT^fy43HGhW$%J-q0jhV;p9*rhS#q-N5C?!YW8gjM4? z!pv7U98DCrS6FRJH)*Fm0=vWYbmqwxN$b5Zn07`WTp|J)0v0lp`x?9ytIb$tU$GT| z3<(RJ35KqoelNwE{>u7;u~`UYNLc7hp)qHsy}Zs#vGChKCqu$QV8XZeYAkfJ@nWGe zT`^dwWS+6mnXWu61hNEH(dDob*)nt{ug9Va)E>f-=qsxngPq+y+LAV|u#GK%dmd_P zao_gkuzJglZJbMNKQuf72jqzLp3m#0SY!X{;2G=R9J~|@ZqExtVEtFH7KrTM$BNMs zBXUo}?mmPy_i%c+-vccFKs+>mQWELTw3lup`;!uGzc<~FMDZgr`~#W(fiOY7=RWcS z_fQ|dn=C{PJUWB>j}}3>ukKM#c$uKUOK}P zd9y0$mh#P$Rg0&|mrX7BX=dJ=cUeyR8Fo(8PI)Rb;4#?Ux3E~#NQQ)oWhZX2rd}^Q za-&^{iB4W4n)bMI@-x|YKU^^5iNddM)2*Cd7UJK;yrCxS7X6y3h0oouoBRxpS6ec$dJ(2ixYls^=DO4yyYjCZRAE-~wT8$WTXL>)WnNpl zY`Xr>S%%N=LdK%-RUQHbk+Ir2JUrsQ4Jewr@@1_oK9o^?6(&zu7i`ZK^r#I`vKgx# za9GdhMZ;RNQccL-B$svXAc^(O{|{ZYy~7 zp`w+O^sA>iX*aMRyble_^M{n)zCrhGLwN~>IB-BgU$bg^tFbzUUU)gII7VT2Z~rCs zoldeZ+uT-Z_5AS%35z>9(3%)vPrcD{IKX@`fcy3==DV}f-khcT@pj$Y_lfU&q>6V{ z`IgD>OljV`+c5E2&BSL#zfZA|ujjse`}`y5Sg1^RXT@{h5brRdlc8bFKFKVav(CC= zk9oyT z^gO=FUKOMwGt7k+i{9u4j9Bywb*JBn&p%~u{gk=Q-tH)`s6fL)XF|t9 zCqu%b=4KRBYWB0ke-|D|WW`EN%K41oy@koH7^=G&9y^m_blTrcUGvqp`OhXSme-YY zjOfh}oe3QaoeT-fY&LHb$L@{UFDp~i4({PdSkMxyo9fT~&4Qn>XeCcuXDmvNRM^UB zdJ&uv84HyO9Sfc8vtN<0tXAvD=!mPp|5{wrAUcSYyV2%aIH+$qe1bO>@`+%Cw$XY1F7;8-w$FKOpXWI=lyC~SOIAD{kb zWQGr6;T>rl1vQuN?hsf6*6c90eEt5$pa@5Bq&s!{!(m+g{VE&A9q_kDPy6u}M+iS;3omGEz1e6e zDg8M?>O)w+(KS?o7+!yId`f*ogWYZirK+l`ii(O0-iFqWMrrvQPAgVt4D4zbkByE} z_@dt#S|7rKtc@V|!Z6U^($WI|J3BiI3JUuB`!B#+Bt40p`0z8a4!Ofya^-&OH4scKm~1`1_!>!Y;FU6+VXr zSuCiGrgESSI-O1+)9G{RnR2=OTr5*@-l6!=v{H%FL#T1rbMG zjz(CuCho6Vfxv?NnpU(boXpD3v7Ai6u}sI~m|0R-_-lGGY(QXLnBSz00000 LNkvXXu0mjfa-54Y literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/fk.png b/lib/src/assets/flags/fk.png new file mode 100644 index 0000000000000000000000000000000000000000..fc9b5db4c6df7ecac7a62fda15f2c246a59148fe GIT binary patch literal 2230 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 Ef(L+U6951J literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/fm.png b/lib/src/assets/flags/fm.png new file mode 100644 index 0000000000000000000000000000000000000000..8f5b1503b4fbce89fa62f04762f055fa8db0c477 GIT binary patch literal 595 zcmV-Z0<8UsP)-VwB5GX z?WWG@i@xIO^ZM=e`;o!qez@S#<@DR@_J6nEc(dJ}$>*ZW=zh1~^Z5Mr`TU2x;j`52 z{Qds?{{H>`{Z;J{tI+D?@cHHO`K!?D>-74s((8M*-muf_vefK*w%_&o{j=2V`~3d2)$E?g z=ZL)Fwbt#Q$>({r-nBys^8f$<0d!JMQ_#jW3bFtI0U$|4K~#8N?bpX@#xM*3;7WG( z&cFBG-Fxr-{twio&|6Iot_&&GRfZ2?TS!|<0u=-?q7lv&AWstoi09EG#&l}XBJV@S z02muC2@z}rkVVj-y%Qb-%$rDy^k6oFS7M}Hx9xhH7U`}{M01mrrmbj1BjaM=O&W1e zi;OE*8c8Dy%}Vumpjt7}ic)FBf!fit9}2R5)Vc;o5_ved1b|UTlpl-$;G%CxAmJj2 zA&VOn#$BF|gGDG&iP7KAD;bE4&f|9_xAJ$=ihNP2yX>$A&fmPQ;}hD~wK~IsICoY2 z_;G0(q((H7?3;+@Ubp-cB!1+xaE}<_bAXs5((flb4N7GBvuVAM?~I@H|HSu@9+})L hKzQ>%v=xo0h%WOnCkS#l6)p3R^dAo7Mf*bm-wf%dX zfab851o;Ku`Sk1ezkjdXS*q6og$g`f978G?-(G8EYcLRK|M*`}TX66H$!4<(Caier z<#zwLLA(47v&)rf`)W3Oz1pM{$+WYz0S0`;H`llXbt*ci?sMK#uUwqE@5JlV%qdr@ t8ygx-svhlZm9Ccjx%P;l01VVNYS7HwO7_RoVy-&d}G zt7*xgJazTB?YoVtS$F#Q65KAumvlN#XZ$v*z{9@~(j*u7OkTFVg6mv{PhjuliEfUB|8g6)BivnoAOb~V2U zC@Amg;uuoFn4EZk^@Wx(5DHsKu`M=QtXUY67Q)8HAhMY8y4~NcjXzopr E0GD?iNdN!< literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/gb-eng.png b/lib/src/assets/flags/gb-eng.png new file mode 100644 index 0000000000000000000000000000000000000000..b534e62892876c74035f6111e4dcbfbf38a6a119 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z)$P6S`eeCT8QfvV}A+F~HRsR3~|L1j@6Hr9L v)5S4F<9zZDekOSdH%+ZTXVxA!(NIl>m=X(n!K7toKs5}Wu6{1-oD!MGJTjy8$JB)7k0MCp^yDnq+fQKMVR7GLa^Y=!;ck54Z++r#eUG2Uke|kppvUKkl;??* z=#H7_kDBR`oavLE11Ep*w!QGTzS1Q+_t)F^*xdZ`^ZoPm{q*(y_4fYv`2P6#{`va; z`uo!+JRaR?R{#J3H%UZ6RCr$P*0*lOKnw*@-d%;4gLBR~=l}mSLxo%{D9qc&Fbqvi z;B>^bvR2#X`oOvilHyO2hSuH9#+IHg?qgF~Ta3T}!h~co0s{yWk}V@JfG{E1%M~zy zFd^AUzyQL87B(0I0|*mgZbl3vOc*eXFu@EXOfUlo5E+b*Fpa>`jxCFm&oz=52Kuo7S#hRi#LkUVU9YdsBUNViAfI3F8qk zxy0O?L<3-Q34h!HlS}vrFu8<}0Fyxg!VD9LFvA2R%rLIGe!g>%oq`j jFk?h8!i)jI2s1n1HhxjbqyPe100000NkvXXu0mjf0a6BT literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/gb-sct.png b/lib/src/assets/flags/gb-sct.png new file mode 100644 index 0000000000000000000000000000000000000000..7f5f28f40c693bade8c881e642e95e931b56c803 GIT binary patch literal 468 zcmV;_0W1EAP)K}N;O_b43mC<~#-QDW;-|Y9X(Cf3& z>$TGC+UfP&>h>gi#z~RT_4)iulF;}1{Re5k`1}1KdB!4o#?riqGXMYqGD$>1RCwC0 z)>%qJ0T2bz?w7<_<2>vBmnnWo3olR?Dz$-z^V7F_TF$n0q)yJ?d#e85{;H1B^=G7p%d%85338{X)`KaH% z?!Zh)U0l{*U}mHyFcVS}n0cvUGcA>wIVoY5N(r-6N|?n`!c0g7W=bkI%cYcACS}b6 zDR0J7-VCL@8A^FGmeOV{rOjB%nr-@E%Sy^D&(A*C2L7hqQ~Wpmp5njhmnZ*CFU4kF zip{(foB55-f75St{+oWI=Uc;XbT;!F9nJhkM>8)Km}#lZOi2l|R7#k|Qo<~i5@tdw zF;h~xSuEwuA}MdiQr@gs%9|BSd9z|EZ&obj&5EVGS)r6S+x-C3Pa@|ANv@Xw0000< KMNUMnLSTY&8}HTt literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/gb-wls.png b/lib/src/assets/flags/gb-wls.png new file mode 100644 index 0000000000000000000000000000000000000000..9571ac5e9b72c5f2a51a44f61e823d8afddb4354 GIT binary patch literal 5774 zcmV;97IEo`P)e87B4U*$Ue>p|m)Gkw(p14eWmUEm^4WazWstoxi3mOU%$!Q>ORS`3FUcxwH zaTtO}Z{NOs{`@)O>&~rP(QX4W1+EDKX}Z7_J7gp<&IU%BCXfYDqBusHQLB}9(YohP zpZ@5(@S^lHK?O9vCGnvgG6XI-A4rJ+*#&{CV#d;+ zc-?J8asTmhN)k$mKqzh|RO9Ep`pQrQ{#9dq;MiG5ZGQ8kgh`C^d4Y>=(fW$nnwxjS zbkPD}L3a|v6)(Q!aADSMeb*7O?DS%!FftwOg!sC^9!7QZ@)ceDNak5Ts-qw<`H5!GdQ zKvgHiMIz%I!$`v$w9;3`lz!t5p(m^+56QM82Y8=Cfx+jgMB z_g)T?tL)mP30we#ISN1=?gdi9a7r9TiTx-CHSNg7CO6cbhGBNgFD7E9ErX@5cJq7p z?paK;GR_1hRcngpCNr{=vQ9x8cRl0WU2J6Q^IL4rCPo9c0`3;N;owOS}jH5x4E&#j4GSv9^kHety1%vtitt z9U+YPYzI$epRua0UaGc()UEoerQKBa?T!kBD=RfxTB*T`N)6ZYngCNjTC|sMog#2i z(T+&=2l=*~?!x&TTPNzw?V#Hoxd8mh!H2xVHSFlDfO$0Wf9NdU8g z_ipD|t)r~AcI+Rx`yf(8vHHufc@K~>Fiw~cq}L+Nx_!s;rNia3A*ZLz2ZtdCNR$vr zL?TLL|DIkN#t8!%P~+~A;TL+^b6glL0!Di(*{DIfubB};Y2RL3ySZ}ItYU85j8toC zHY4HYLkXcrA(V*ZTyvN%u&jZHU@oK(Q3-%f^6iiE?T+$oK|n3-q;J(fEj$WeSh6tG zt=mC3g*m|20$&5|blY^vVqoDN&?Z1bGDyjMoVe#0h!bSxrfJ#lenH`T29Mn=jpH@4q|g6!;49nr1cW~x$z6cht@>1iiSB%r?#BDW;7(!!&|dX0RM zS9*I@ke46INMgPH621L#s9vxJJW496+J(pXc5!B4B{gur7L!oycA$nXj~IYW&^YX% zECA3b3;fu`hj2!501p8Z0K!$UHLXMvG`1UZzp(Vw7P)?hy1EMh($s6^+pq;Nim2=u z!=fC&W&f{&Mf#WzA3k6ozsjLgz1s~aH6K5H^5k^80k9{c;OjA#^Blf`?dJZ(HgZeZ zd))kXBqM#DmR!CgX4nBGiz1G3LP#PEaR#mu29-MWHJasQUMj0qgfCExyt~=>3-2=; z_HxgOiUH%Xqn@q}i@!O6g$Bgm&Ck!`AE1pxvb$eDOrY6_C$ zvr zdA*7!MAvP8TGAdTwRKwL-_0g9mumfv>}%J56|BqpIK4oc!Z<7U97Z3btS0mE9Ookt zr+5dJ-jv?S4zO>X%DM#Ygu?-RAy-%yed4SYD4j`M{|Q!B762t>6rmNS9gZOk^^B8& z9l#3)AR0J}2P)W*gqeBCn(6=N1Y{W!qN)%+vg;Gyc1u2d2YIj2<{1X5*#eEUs#$M5 zJ)m{}u&PodTKJ%5BsY>$OD&7#orb~~1c4+U;@e`e0bvL|Hg8rG9fuT}zFFQxTp-pU zaKr{Gj`;OvLBUDf4uBx@I7DEAXi@BlU~3Cp!n*)m(M&8@%RN&)VLsuM+@|e;5tENk zTX3vZca(S>d=Yb2Sbm8{w_pvJVnjPu(*+ZoTE*44d~;cAlDg`yT-CmthvKja65<}7 z4Oe7csN<&S?iD;`f%%Q;hrI!fd1?cvkQpM(mJr}M3=pabY>@@X032#1Qfh%I=%`Kz z+dRJifYdtCqh{eQ6(b2)vgQwE%*|cev^|HHs^=(lxE2NrGGyGehkP`u>WJx!%WNU{ zo%E$dpdK7Uxdf!ZL~sNysn{+$T_B5HvH=S|T)BvyE18+Qty^-faxf*t6S(CHOpmJE z&IUKiX-9u)CzQck`wlz1X&ZU+rL!S1q@Zopf9IGf0ZZ2%=rLGTMM}N|1NpZwKi~3; zf2If}Q4=h9Cal_4str=Ip-xNq8A(eJGN({gQ+8-OA}EO;U&uwGy!WWw+}s-}X-Nl8 zDkm>gcOI^7>`oR4jf@k1f$uTCE$~HtAgCe4a7ZfKk^^1W&A4Qe%a95=>A{X-)GQ-= zS289^AkAO{oa>g*iWlbn1z;r~JVi8{m4MbSOIy#*ic8|M9tOS=y$(X@AkPM}f<^>V zjRwW1ieq$Rcg#8WKyHN7BCOsaU}1^m02=@Y+);}{$Pssuq!l+C%6{YV&yjMz{7Se| zHEOn^(@m6es@9eB>J6W7eE=dAoo*5I)| zWv&si>vtD3z&B|}%mm3pSc$=0#g!_-V`mq$xqtsYmT_58a{;G70f2Ib@35a=6oc>+ zPQq2?d1x?jKU*^mDA>5lECXuD(LcmjUW=Si_b$^)m;D-N5l*cuY1-3?Y3B;_pFf7R)) zbOk^_@P)*R2ROpf02!;V1;-a z=C=(Kg1RD)%6oOJ`R|VQz^X3~uB5-D8`pizRvDf;Djp*|-`y!7wkz60yy~NKM$+Gt z*qT6I!J&Yfb(3=$`YIoK7}u_!CBT6TPE6KhUOZbsL%0G#OsjQ@aNFiRWrV-=c=G{Y zUSBS|t_HE-{~j!iv17$I-SU`;1lKu-wJ%at-Veapa&0CVI*Zz>BOJ2QL&j}q0Al*J zxaO9xIea&qJ}ezPl9>2vOgV1#Brq&2c<&fQmMHfz8IH-3{n*1SjT&?bVi_GWLF`r;#vOn%Yed`&aP)xc8W4P(uI>=T$>U_UK{-HV z9wSKe80YP!Hyv^50PG$#9?!rRt~q@cc0dX?TWSDL!Cx%ewr*Z_`0Aa!Wt!AwN1|vA zFDTD9Q|aYmvMwSIT*y3UHCtUdO!yzc%H7Spr?teJ-DBaie!^1^Ohr-y3fQ`sD*$ny zM4}$mGKRAfobHIds3O5501dCPtpQjunR^*zZJn7VQC&9oBmNV$P6;#lP9zR^{eTHV zryB;={GW|~@QmYT=p>^YFDM-tgMtS*w~WM!2K=k$1@0hn zE!Vr|W7-W}Hwr!R_p1MI7`8o}7xa6+Bp!u5iLDq|Tj2;`#h?#3V70X3Ne6<+g`zlo{+M`;(-t%5~!X&yrD4i%0k#O*fZ#2pj@FP#4 zpga^3T;hM>RjYe3x7j?hE1jhn$^2XI&fSL?yi z7J17*l(c|`xDvEggyoHD-zChyO`ShfzE{MyQt3fnT(ZHl z_{Sso-Lb=k^CJD!tBjpa9}QTDh|?0~#(+o83v^X~GNreFMt=dUgzvM^oPrZsvh!0j zxVTc|U&Y|@++(`yyq30$BIuG8R#KvTD_iMurM)-;c2GGrkxsXQo|769H%c`4H6C9v zfONSN95I6~=_7Ty9ee~}VMG_l_wA!J#d}D>LLud`;o@2dNEJTCIsOm$RH_cY18|@i zOx`F3&dF@lRN5&Pwvt9&CP|VJPNB)SG3$HFz4oj4mA^`?XVrU1wa&Q8yM-bo7UGiV z(Rda{r<=yRY3imZ!G7{P_KL`1g(3j&Hj1O_LS@t_0R#kQIZ`5&>{jEGE1KFI+N8gf zNnsdoKbT)RNZ%!&q#}6FNDP%j-XRsnx1(~-YoD7nIuk7Aw7)ujU=m(@*OkdljU}{N1cAU$|J~CAj`uR{)Ly~}z_ZM+K3d!|h0+XjC`{61>1 zl1J%w1*IQ6KQ5FqRB7wOWM8&L88oGtZS^f~Km?d}y<%(#inm-ohzXoryx&+M?+y}M zRV3wZP~4)TZpGx*!3td|lEDUGRS-OM>Ei{~fcfNGuigOVnW_iZCW#uXHKnHfA*|b2 zWEmYci>97yCCAl7R!2mXM{k)&L_Ce&=|$aFLy77EV5P)DJuWrvDB!>PFQE8-6JQ~1 zM@}P;K*496(2?xn(#^Lt`=ov)PegqOlAb+G#&TPYwSCIuLE($Qc!&*}4m z{)$ZLXntUOl$F3pux51x%vHLP)|KhJfpe>bcD>scH*uizP8uu9rPs5R&(gG+BT3c~ zt;;n-UCl;MBpZpq&slj_9_XJY)N`?^4`%LVc?Y${%m?m&IbRXBD^^^4k82GD>PMz_ z`^>ALKI>?(U?j%aLH@T))`TU;^8Aa$(i4<@?bR$DKXzhUKA%z-rR!<$g>>v>l73Y0 zeojXN6MTe%?)5YZ%KN>s6vs7SdL>sGGKZ!#lN#K8To;USqop;)rROsJFS+H_{YZ3~ zGGZ2cx%gozc8+k7)q!ByW8sNor1^ctdj<4e4}01CYPk8wKoB*>8%R9sRkuvNQwIhP zlmuRLn{|(eLX_=c5<10AUWG=*K_U;CNgY>=*7W*>;o|i);d8h8gmgH9bRoGuiwvUkms=O(ow*a5ZSXI}M+pKU28#tPc~ezHeY zh0~9ysBcghp?8Rv)SDf?*UfenOhx7bLqSYd<&dqKG-njeJYlq$^0JTUeP@%v8ZvHz zENxRp4htN}DZ?6?90>74skd{qg@fg+6F4{M5YOU;LfX~POj2U$!_QOIBMM#Lha6Mc z=&2;@pfY?WeLGu$%^=qsp1}T+Kv&?^%qfOUlW(PoAENJ`%jOQ3`!1xVJJjqGdU!c2 z+o?LvYU3vnyaz5*;SpA7f&8<<=IN4O^oT`94+(tf)zH=29F<4Rq$>uK`aE_c{_7#s8iyx*c`>0&HPlHefj){`be$j|7VT0!@ zJ+2zA{^L!87FGB2suz56u)?oR(4@+3OR|l!#lI z$ksQ;8vfo5LXPoA@VC?bQ2#l^w~h51FSyU>9RXJND@Mja^TZH*bUXNuS>T_}? zZK(hM|5k3P&lD@-=J4B2U-QJu0w#V`Y^c=Q=~r*5GJTjy8$JB)7k0UPhit1 zJy~$7TXL(`-0Ilg>yDnqkDtchVR7GLa^Y=!;ck54Z++r#eUP8Vk)X!|Cx7RNl;??* z=#H7_kDBR`oavLE(j_|Zw!QGTzSAZ=_t)F^*xdZ`^ZoPm{q*(y_4fYv`2P6#{`va; z`uo!-JSN`@H2?qsH%UZ6RCwC$*SBuPFbqavik92$>Am;f^Zt*PtHBur8Yf(WAn=)g z;M)XBs#?1?)*9(AsA~L9Ra@!rWPMW~&#z;uswGBX0AWIPi2wr#6HDYX0s{yV33dxSKkA(5?)5pY7+1a;peNqL__%`bS9og$86m2IP+*!vpC< zTBG84s$KV|JE?=)j||Bdd$U)a9EH}X=Q8iAtC(87deJgR%6xTq@dUp$AQqv>kuV+s z<0aB|O|k6y&T#+7v9 zm9$pBje@sMWY(7hSSHak)yK4FDiK-seO(P}YUw=dXJp#5DE%KLxD3aC8dmkHWs(f8 zKX_IC_ZR73)6Mnnl4j7V0&uxT)iS>VD_Z}?P|9KT#;ncbcUf>(OmJ=V+PrX+{QWIh zBw<9IsT*?zdaB$B6Wp1yF*jTzA7z6@GK{J{e@nIyFYb}Sg?U@D!yWR=C9p{1=o%|` zWC`=)5);f`u{{f1AYWV#i;!)&rYN@0<5POP$LUwY+Zf{`$lY-R?F zRA@@YV~0GHi3x_mJhD>}u%PGz8kd<-?)(u^IhbG!OoCxBPg$@eWYuPu@i}2;i^=DN zrRuCQ5+;ShBE=lgsKLCFw@#U&9@EWJruy?r!T_>_16ZWk0~@wnRQ$miL)2ixM3@ef z((IhUBE=iju=CO)&(7;yhY5pY3QR;Zatw=C>{LTYe7EuI z3)(&_3ML%ffM#(MSfpe_>J3|+@53ea7d`*5SaYkCg+ft2W)TTwQTWBi7-Z<0d>D{M zRuHVblPk+;P3mEFCv3ToVO=28&@gq#w-5T!e%LKU?!cBrj%Sn0>skW9ap>#tYS zbd+wkpty{%=q$@`L!^ZQvRFf)iW^v1%Sb=Ns~N1QS~E8b(*0K!l;vl5A!Wp*ZzgLa ztvM%ZrKt4j!K6mi6Uyhqf|rdVWs9DdAkD~&j00-P>3q$?T(*gyMsYEfb}~{`t6PM z68lD4`jbKeSrmS;F)kHgBaH#w5LQA*i01W$9}Cg!QbRu&qQS846QYUh2>v}i=fdD0 z2FDbbh+|l>1~h85sM!6e3M*qGgq1NVXRu;84lHi6IIy^J(tcn81Gs=iM`0G`M`18S z$*>f9$jTlTN5}U^53)bL=kH=j4u%&)aCc|(ZvL(ueK{=d>dR~tx8Y7O8<*LvV`{n_ z7G0C1BN?s*7jR8dKhibVBLt1-G;3a;U5H{AR! zSc!+&UmCz|dW`7ydV5iemj>YSufUp8%Kkda-bLyED6N~G8IDKwo2&>$-6~;W)t9r^ zesM7Kdc2mSz6@a9EMj@qNB^j$G4!k|qa2*g7-=k7Xsk@NMt=w)fxn^J-I)x%41L5J3=hK94O5 zq%7b>+Va57xs>vaASl5pf^-f7lFJbt4F&`8@kmGji-puw6cjA=Wo1yS(bNR16$1l! z^9G}%a5^zQj=4FUI)&0wgomTN992~~cn}&58XC~p2o49$&1h*sYb)B?U^3y(9mK^U zEe&=%GBV(BAUhi}8C)(gA3la$m3sF>rq@<-^hK3*#p`rpR6*g>uSd7q6)Yd|)MOGFJ2F%an z&mYv+!|%u9;t~X@6hn8SuP+euu zbR4<-m|Xt+x5m(9R@PNs`qX=8e|ury?9c;*3&a=Q(hHQVl%0m=51r0 zgZdAP<}C)F;Jt1aGyl={RcV#7ZM;z>tw(Wk`gFvToX@tB2wwL@aOOjcTN%B^Q@>&) zQ7?;`9^tY=R#l%NS&XnYZMTH#dTJ5)>6=u;!dE6T*EcCubp54Ch}c`P{TKAVr0Sy) z6jeK!%hdFDr6WVx4qr^SrX6PUtE*7a^2RD9Xes?y8~Oo$7$UC z{hpn#ALn(`xKo@~=S{MCLiF*t4{Al~RNQg>0E31ts1fHD_f>a~-g;my$ ze+6TMmKL6_Mt50EITqR>*q3DxN1o4qr3lNn%aW{0=YYC+P)+^5dRd?FT$lg2%RAK& d3GE9O+1Kt~U+dqfpA5`I@HxqB^P%I_{{cB}k+lE- literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/gf.png b/lib/src/assets/flags/gf.png new file mode 100644 index 0000000000000000000000000000000000000000..54c2d5e93e0ddfb06a27a8291eea44ac700f2065 GIT binary patch literal 738 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MZ!3-p0rv|)WU|{49@Ck8k-XgpIgwU#kqN@&y zuR0{Y`j9w(xBlu&l94$pDb3koa9LFPikOsOi~b!s$-7FDLe2VjRV44K zO5W3uxTh(>+iLL0Mf9<|=wlDj$DX1uQiY}K^j_u&y~-7OT`lx!0pF)Ze4iHceqPS^ zWex9_wY*<9@+ws8{y4$?<0SXbQ(SggT7PbFx~6IUxx?w1qWNt<&&y2VbCS|uH}QVk z$FtbO@*6O8L`s7Ef>*6N00b8Eakt5x4c?)x5(F zBCdhrikdg~CR@j(q@|^`{r^8HYUP^Xr)NXIRn9!V)b@Jz%QwfKNABD2b>5ges#ebM zXhTPmgNvcUA_;*&o=%N67m;SAE=9qk3p$cKTnsf9Nr(jU^haEH#>^qC%+e#sbc};B zxuwC-Y17dur~d=Vo_=Af#p@{Y z`Pn31XOA7*r{%o3e06)o{Xemry%$Z&zVSrwL+ta{^_{Ka&(yyEHhR{#@Njg^G$~>4 zP_B)uMJiVnoe1pW`6cmb&rGH0T1&2-ehrU)mm5~*HSx`Nw3}nyduEaFbFZ|YGL1)W zx1NrFyJ*AbtYtIQl(x6`ul!!{Ar-_<)G^>Y>tiT6VNEbkhen$-!hZoShBir#yU#1$ za?tNW_qoj?3B`mS0RuM<3FVd^L8oIJj>#Ah#SoYZ*ZZ_3>OVC*n>y85}S Ib4q9e0Qf>Wm;e9( literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/gg.png b/lib/src/assets/flags/gg.png new file mode 100644 index 0000000000000000000000000000000000000000..e7343041f3069e3af0407feb9f0653e948887458 GIT binary patch literal 306 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 D3O@mC literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/gl.png b/lib/src/assets/flags/gl.png new file mode 100644 index 0000000000000000000000000000000000000000..3a8ce02a95b7a486e76d81ad487ef8f85066862f GIT binary patch literal 852 zcmV-a1FQUrP)0{{R3U6oMi0004TP)t-s|NsBj zFHq17Gtm<{(ic6`9YNMBP1rS6+(~BUdy(mnq4K%K_084!-{kq=<^A*Z{r33({r%Aq zH|K?!(;hq)h9{bRdL-=Z0wz_?VzviqOt9yviFDs z<8FoBQf=yxqV&np^~=-LBS!br+Uk;|)F4Fbm#F&Y>g08c<#&zK96|i?^U)7A*f&?v z5H`^gIQP}u`|IxOnW_5Z>Ev{Z-cxSzxWoGA>-*{L`|9o0BuD=E`SG~K+eBjj{{Ge~ zOn{0}ga7~l0(4SNQ`Gn%p|=eH00EFmL_t(|UhU82ZtFl82I2G#Gc#kEnVFfHxrZ69 zzW-XujpNU|+enc-H}Gh5RVh`4Y6j5|4bhNpyX|13@$2^WW!&>V$dzp%gqQSVlheYH zk6(O{WIX>Z6lrhXLz({1c*P-k6J)Y|Awy9F@(GpGAM+!fk5K6J zGcV!{K(UC26A6Qml@D0}rA!A8(%%A7Ssr8@v_fYbNDGK%*%1e*84}FM3dsFoM*f1_ z5-Z|Of}DjFae>|@E7A%Tl^BsCRP>XG_$7Vtt7yVcN(V`!DHUCS)EgwM!uaQ7M21x$ zKfs8j+v!LrD}pvUa>R@@(UC)DBtkaadS(P`RAdV5NH5VSJa8cQtJDz=1UZu78R0?@ zryw@)A*PtJ;mB|zu=FVz-`By5pkBd941ym))LY4L??VKFoLk;-njr>(*(qmi86gTm zGJ02zaP0u%5FijNNr~9a6T~9GFY8I+RY=%-h5+FRfZImv@|^wKY_MTB1ArBwSL29= eXo!Z?RiS6IEv}78&oD~>0000+qdM<|NsC0 z{rj(EFpWp1N6n&d)2Y=~>Mo9Q+sd=( bk`TjXeWo1^8cH*P<}i4=`njxgN@xNA-y=!x literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/gn.png b/lib/src/assets/flags/gn.png new file mode 100644 index 0000000000000000000000000000000000000000..609fd6645303bb54b32330ff2af0fdbd106ef1e1 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MZ!VDy5r0#tQq~rp8LR`-Ys(oHB@%N(Gw4Ejl zQxbsOZ`&mPTomiyZU*G4NDX*mUj&laSfbuf00Jlq@5yLd)1e+?mBi2sDQ!K L)z4*}Q$iB}$YS7HwO7_RoVy-&d}G zt7*xgJazTB?YoVtS$F#Q65KAumvlN#XZ$v*z{9@~(j*u7OkTFVg6mv{PhjuliEfUB|8g6)o2ba4!+U`#5QE6I>?UM3;d zx7pxM>YS~)x3}$;UIQYpZ+n}3drj{4<1cp4)qfeg`NW(%GoP%r^xyygrG5RQb(QU2 zGh8>^5hb$5+u~{NPo^TsiNANzav| z#RN{xd%x|V@acQ&FD1uvSO2v8U^zQs?SARLW48tPtRB3n5M~V5ZJH-$VRg^*URvwk zpMf)0=Qo{S+q(8s!4BWg+ieu4c&oiIoaGSKC6%{wCu`Yiv9jH=W~&9|`k(tdf4`Yy zW+AH<@hY$Ve4O34#)8kDr+CG>Stok1?A^O}_T>jJTqbY+ZN9zraAMP(0)AfMePk70atOF`R7m=jbp@ zI4e^_h{~9 zQsP_qY?jY55rNXb*QeTlwauAh{!_nEqSvj|)>-xcrbizwYV70}U3?+mFu^#i?jyrA z|9`*y8;>Lz{`gy0#e0+gWXMH}Bd@sH{U!zue~te#EuVL?u)4N(Zil zXFh$8Q>VF}U3#|fU_wB#&abQ1bNx!A4FnqQFKa%Z8UA^7f&s_&+q`?@{I6eKm6egP z;QEBjd^PXYS0C+uzwdCDsJ6$YRS(y$U7K}v#@RH}k|kTVZq-zNk-Hj$l+n|ouzL8deF?d45PO<7#-%5k-dbgWvXwI*h#(CO*=>Ka>;o^&K`Dc_`%2X0pI3NGF$z%fe zgyQ$}*j^v3_GY$Z5X?7VQo5JG=CbD?M@L1opuk5qWrat)X%0uEdm1{-B^U`RNPNc2 nX!QBa>$BgOzvny`Jb6Cgzj literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/gr.png b/lib/src/assets/flags/gr.png new file mode 100644 index 0000000000000000000000000000000000000000..ac2f75c5ca8f9cb558a7fcdcfdd77c6d4a158f8e GIT binary patch literal 308 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 Tk59z7gM!`D)z4*}Q$iB}Z3~J< literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/gy.png b/lib/src/assets/flags/gy.png new file mode 100644 index 0000000000000000000000000000000000000000..36279ec5cf2b47cf54266b8f0d471a933fffef2f GIT binary patch literal 1006 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 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ht.png b/lib/src/assets/flags/ht.png new file mode 100644 index 0000000000000000000000000000000000000000..43e208b1f035c57d45603a45bf2f1ad9f79b8d51 GIT binary patch literal 898 zcmV-|1AY97P)~It+mRyeyD;}k6ku=LOXp$RFGeNrGNSK>HPfsvBb7GeLy*TLbS)Y z`19ua`10DqqsW<^_xASg?(V|1dc?$(?Ck8rla}1XrvLx``uOqs^yIR8a;%4=T4;mb z+tK6P%Hqj{>eiy;+|AqA%~oQAuY{kpd~o~q=k@E;;MLD{Uyf{bf+<9SYI1(sy?5Na zU*g1d)Vz0OZ+}vroHFHf2?0O<#ZwGKGD8il0zm`uX_w_xhxhwGA?cd3}XgWO}JjK+Ie^(StV8 zeK^ZqIlV73S!Q{8eufP*hozLX_xAer>gma~ev^Ma$e1F4a6p`dI?rfU%Z*gbi&)NS zQ_FfKf^a{_nIe*YJI%I&^Xcd3e2?$AyWrQu_Veo2q#nJL9@(N6%6k{TL>ZWVT#$QJ z!a^CzeHPcE7rv7o;Hnw-^6B2y!SA}f=Y5a*`}(-kykC@5k&hmUfGVPuDtvt`vx679 zTqCwpB({SVe1I;dmMD#ZDTs_6X_i^S*1z)W*O_`~YJVO(cNHCR7Cn6zNsLZEgFZoi zDnxn~LvblZaV1847D9e4Lxe?9k6Jr^8xn68M|>5CktU>iZFY239&r{deKnK2oRhno zY@&FDs*Qx9ii)U_hNO*jiIKXQCVDmoY!;wYPiuNqYI#$k zQ%|1{)DHjv0LMv0K~#7F?bEeE20<8v;hDqTB|#!QBBKJF4e0?opb$Es3h04SAjA3H z?cC>yHhb4Th=_=YBpTrm*;xFes!#|zGD4KF=Ccy{fio6d8LuHKLXEHxUWDuKV`bLc zCc}zs6~?zGDt0IL4&dA{oSQyki*QbIGS}wJMZ`FCiNy}MG!9vCY`#Mn*LDBY-gta~ zQ#5eqnBAU(KFRA+mlp&bx$TbJ1s+-M#=wVhiC_UB$_gl3g;OR1iYTIpB8n)Yh$5a9 Y0ihJ!#|S8pD*ylh07*qoM6N<$g7Hqt?f?J) literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/hu.png b/lib/src/assets/flags/hu.png new file mode 100644 index 0000000000000000000000000000000000000000..d181d5d744c39bc301a8269dbb94fe93b50752f9 GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!VDxMq?3Dr6n}tEi0fG`yL(0T|NsAQoY&!; z?`!^`{5nud&C|s(q=GRyQ9-gNMt5OLp+YZy}FT?!GPm{!HQoD|Lt!}JCqccoj=)? sx82`Qful*`#J_kQPDcTjpN?#{sjC>y{qQ)q1*n<9)78&qol`;+0OFW5i~s-t literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ie.png b/lib/src/assets/flags/ie.png new file mode 100644 index 0000000000000000000000000000000000000000..10fbab9caf831f18643e071397d3024840ff5646 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!VDxMq?3Drlyrbki0j>tFYkSP`Tz7Dq|}N@(VtC?AX75|4Juh9tDaRd%8G=cpOjmaAxk5&2ZQ&!)wr! zC3)3oRcgrT71IKB7e~2m1qwvy9?LkOAi}$1#{x!%Yx{Cmt_s;O0jQn9)78&qol`;+ E06-o;YXATM literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/il.png b/lib/src/assets/flags/il.png new file mode 100644 index 0000000000000000000000000000000000000000..32aba13b1658e2a7a65bb03d57fc5135a2108376 GIT binary patch literal 659 zcmV;E0&M+>P)PG?(+Kb_51Yp{P+3&`uqO-`~Cd={scR@0y?>8h}CF`)oza0 zZ;#hof?k*VO5s^J(*znZY)o3Y~=OuwMD<)OCaAyUDw z!RfHU=^|6Xz|QS3UB$xB?!(aT#nSFEUdGYe@;GG33qZR%Wysj!^xWk2L2JqjLAyh2 z%kA;{M{mqXaLfunyHt75RC>=#Tu){gqFKS7d^k|@ zcj3Vw=pJ%@37k*K#;?Jmdxlf_E-MakcLCN#ebPN3lZN@Ao`ZCTldh~!^6h6-ih0F4J@(k~TJb4Q9#7r{Y$tR-x{lr2v^aZ6CgHXx%jB@}0002ovPDHLkV1g}hV8Q?Z literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/im.png b/lib/src/assets/flags/im.png new file mode 100644 index 0000000000000000000000000000000000000000..f54a46406920990c1c34fdd028370f0eedbc41b1 GIT binary patch literal 1374 zcmV-k1)=(hP)y3OK$e3Ez0cy9DN_df6Q z-u%yv1=Vv!D}se!Ay^0&f`wqA6~X%Nu+WNNAy^2OymMdS>dn_@(xTh-sx#P$1^Ol| zb<+^e+O5ha!8HXa8VA!yhpEI8r{%FyI5$QlF*dC6-J;ucPz1GCweIBfNmyDeP|oGw zIj}|5w(IZrEtCM}NE&|nA}Nu6`SQi>c8i(I(^DM=gCTqrt)_QV&S~MsDcrS7#Vaq@8X}rF3!k%s=r+tp%J9m-(K=!~qLGYw6tz5vUG z1x4-{h0CN;E>Cvoq>;&~s;Wv&O-)Klf`no)7=?v}5B9E83O1;e1mFXR%n>wiQWd13 zbYXR9E53a{Gcz;6<(3^jO{|*A59no}bnzX52VuH#_MAv0dhz0g*=$ZrOM`u7Wu-|Z zJ{>0g= z-XkA&>BDVB{r%S}FW&@M-)b{EIYrSlOZB*clunCBSE`1FvJRi<>5} z<~CupZsRq8JbbFCsHnKO_*-%bCe88UFh)!@nM`?kd6t{^Etv1Zx*OWULvJWNfzjK0 zhb7;%8`M2EHuf7V>8Zaf(L@Qb-h1*bfZTP+>D#6>s&lJa{3LVk!s_a3kbGcKTAWVM z`_sGq5kPe4Z84i6=KcHk@f5{K^ECpPj1dhjWP;C1&=lsW@h0VcBoo* z`xe8SzKA5r+}vC!!{{Ls{S=lB3)CJz2MJYJn8S%!ov3aspq~e0QC3z4H?!jt@MRm- zO+qBAx4_N({Cqt@D6s&4gyp~jmHUo;`LV>u$7?w4N=r*Yzd-Nf;^In5N}%+Tjb_#3 zg(~SD{|`iHV7TN%CYscBUKdd^4z!UpYBB;LD6S&7+$E zm%LpE9DWFkn7i`BhYtV+G#g04IV2S0>IyvSctu48-2C#}lAN4u*B?o8-ZGuPZt=G= z#Hm9{^YVeh%a<=fjNqg=FJHcDi>`5?iqe@39U@<_+HmPcy3iIZ5~ym>nP}Tn7CcBaX)d{br?US9 zzia*xVGA=-bs4E94Y|pxn$DlG*i?_{i_ctZhO3Ct&tc;oH%djG7zFMO*)6gbGuxeZ#9s8TYqktE{vfFIr;7P9kcb@~~ZQCPQURGn{AacjS zmoHv`ggHerar0nSShJWjjTJ3AAXwgQ0Wo@dX;Lcaz4E~$-m+n7I!rpEHG);+${IQe ziczc8rlq8^hX$zHqs*###k&r%SS-*20{{R3U6oMi0003yP)t-s|Cuv1 ziVXk&hzJOa3JQ%23ylp8juMCm85xut8hOf46o?op z(gkBwLX!@O=KY_*WRwTsV$TJ$|NWV7&TKOf$v1%@f(RmrAc6=Y8;bl8h(RTgb&*A# z=j#hlL^?28-EOPNBY`2xHAR;v)7hjL6hY!611{b3A)1etZ^% z*|=%RLm;v}rF4Z%A(wmRUc1V@O9num9CNW*%LaYEK(^L;pF45@2z}Zc^_gh+_U0_g z^oPBZBLHMCs7hSKe_^-Bk0TjL4eSFTJC#l~&D?p7MlZ{xtDVX&%um`}%zy55#{IEO zTl)!6O?rAw*sxZUkyaC+?rK#Z1ApBm!gQDH(&vO*%}L57Lrwft_@DR}OCD->U9EQ4 zCDiUxl_Ygo(zkGlrdS2;o_NgqJu!PapqFvk;Q7XK%|~Qz`~!g)wh06gL=Zs)5kwH# dP-KfhegQtV-MGI*K$8Ff002ovPDHLkV1kMHfvNxi literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/io.png b/lib/src/assets/flags/io.png new file mode 100644 index 0000000000000000000000000000000000000000..c7eddc787be75878d3628a70c54acf16b5556ea1 GIT binary patch literal 4687 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 RcPjt@002ovPDHLkV1g@CGNAwf literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/iq.png b/lib/src/assets/flags/iq.png new file mode 100644 index 0000000000000000000000000000000000000000..273672ade3eb814ea1c461d7c87ff9750963cb37 GIT binary patch literal 827 zcmV-B1H}A^P)0{{R3U6oMi0004cP)t-s00000 z007PrCe9Eh0002a5hnlt|M9xOii(N^1O$nRiO&@&@wvbM|Nj60004SD0((CLd_M+# zLI-|A2!2BgfJF>|Mh}8W5raw-gi92JOcjMq7KKh1hE5rWP#TC)8;DXKic}+vSS5{F zCyrYwk6bE{T`ZAaEsfXRwQC zu#9Q3jcT!uYqE}PvX5=EkaM<_bhnj%yqEGGw;@j-x-0kGw z?&sm}=;H9{==1LB^zQ2P@9g#Q?e_8T_w@0(zw`O__4@br`uO+z`T6|%`uzL*{rvp> z{r&#^{{H^||Nks($-Mvo01k9gPE)$Q#5Ww-XcNeT@2Mcz^23W9H5c{EG7Zp)Z>?k+i-N7SBh;O&cgPDJFm&|Umzn9IO zl$|3!Deqi-gb+dqA%qY@Nam4}Odti%!Yh^XL3m|^XnhGlZdJhiFUf^^plmC^&ONJQX(WFlSS8Eou!h1!rD}%QzB) zG$eY=!aNbT(Hb|dhrGYYUEdLV;Dvm6VB0ttzpkOG2E#$}P#> zrde8uFgAcY=ESVv+^-Kg{Sz^%0HzeAMb(AuR$km(22y*9;421jAJlr&W*x}BWflB0 zqQAl_{j@TV6wV5-SSl(PpOi}oA%qY@2qA?0OGL^N-!~{1XfQ*?uZaKv002ovPDHLk FV1j8Vt;zrZ literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ir.png b/lib/src/assets/flags/ir.png new file mode 100644 index 0000000000000000000000000000000000000000..e218c8389ee64a139c0e1d6bb7eb6f34fd4d1386 GIT binary patch literal 2230 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 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/jo.png b/lib/src/assets/flags/jo.png new file mode 100644 index 0000000000000000000000000000000000000000..d5b39dafe70f92348ac10e0c910ca4d01d6d3a51 GIT binary patch literal 416 zcmV;R0bl-!P)Xj935}u>dk+0c6Ai$cP1y5sPF17RgX7lHph+!?8$)W04HU zA{mZ_lMxH3&d@R5FCgq+41o2KW`iP*I{WYb_yAZW1F%R2V37>NnsD%y7#WTw>e~z2 z)}pT6seEEY&0N&86LoAQLWX1M*`3YI9}kHSe>mzLIvx}RbqlFon80PYRaEl!pVinb ziQLO@ELF4hwA{O!o45bmo?k4>5~PZyK%$QA?d8?Y@yX@pwxDe-DJC3C&u+J-S#IdE z*U&C8CLBx9uz0?y3)0{{R3U6oMi00027P)t-s|NsBI z04@FZ_`nf6(o}NWc8=S3kKv1-;f$c|y2kFm%Jtdc`|k1k@ACZf^}rB1{`&j>{{H{} z|L3K(=%%*mth?#0yX&*S#wSh5GFI-u%kj$7_1NFaHCgrA;rQg~_~q)p2{hDPdDLBc zy#+D82sFbPLdGUc(p7W63pT$DH}J*J@W#;b$Cw88AP!m|O|DgXcg0d!JMQ`Es&&Z__b0Ut?3K~#8N?bzjR#V`zj z(K%&?i_9=)e*XvCpJ^SmHB9W=HJ)F9IbI8qj= zK;i=&?T{!yY>;HrkqeM^NkxiBIr3BxkpUnY5D^=LoYD|+hC$8+33&rl?mGIva`qRb#p3vWT{%;rkE6jhM&`(DGGoF81DHF-u zHB1;LNWNJZ(S$tJV_MFL`w1%H*KJz9P`xv{zjsDA*0KHeH(!@yZThLUJ$^p!`hIsj k&;S2#4}%!QAO>lp4@3cfkodK5UjP6A07*qoM6N<$f;_bpR{#J2 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ke.png b/lib/src/assets/flags/ke.png new file mode 100644 index 0000000000000000000000000000000000000000..3017b3b7788b15c439b108564ce9721502c03aeb GIT binary patch literal 1394 zcmV-&1&#WNP)1^@s6YD=Kn000F!NklS9?y? zuj=L=bmsjA{m@Fea^;>g`aux^MnA9+7Q(O)7V@8mg|HBYg|HBYh19B53;zE8pZsEz&hlNB(M}uP4tXZ(Lv&*s8NzlN}4fTaQr##H2nG}(ckt`&ylq**bAERyCw%OJd z6T}KqL``z**0e^^9Olxjj}a0Q!b0-H+O=yzar5R)1O^6b@}7bO!9J4-7k~W~7k~K$ zdrOz5J<3`AyK&>j4N$CEvxeVg<(E2j>fmF<$H!ab90lJAwh2!4=z)vB{YK#LZrx}P z-%^cg9?kd|^iGb26oBQ+mxJQ<>(>Yk4VC+YKFA<0{qctsa_RTq<^CYEIrQu4)vH&a zShj2#pNABbk|j&x-o1OE7(IG4?V++@tC^4oM~_M&4~`s>`&3iu!<RWr z@BI1apGZqf!_~ zaB-oO6hg7x$;qN-i|Cmf7YCz+VT7ERFhTR(zsuKGBV?Dix2EpI#EHfck~wV}^iJB; zsn}4gnC3ulx3>r0zLi4WzIlUfc6ORN>P;6jjPSK8^dHtcKM6)>lY4pht`zd}&K;{Y zqXfUuTK^bBNC(0Hv&lWp%#=c&q^Dc0q23NGr0^&!a1m^mLd{wjlCM?8us;VxzZ?#f$q;6dtu3cN(ueuapjfL1w zG4*{CRepD1AReAPNzmFNw^n;Yi-p*Vhw7j%ROK_KOu@&a}Mf{1c)BA^bOl-(}UQL+IjN7N3W>x*{t&n$AV&oP^Iq{`E8U zh7I{lov&pXMhIW+<@+HS8Bz$X`F;rBF)U0BeNUb4pVNJGDFkod(tUPg-&2P{;@G%x z+NVx@d^As;(4M;P_=E}k7*Juy?7#lfK9}X}tQJChn&-0S80opJQ&&$x@62C4A7@j~ zVomq_Ke(mjgOSAnkSrQoOdpU`JYA2{|_5bv*gw)fH{DTLPMxj0cv zJ$fT)np*8JMj%qCCbyKi(%~CWR+>nJ71gCaRNK8(IsiVni-cv|Q@Kdm_ zOd0xoA$`t}*0e`Ct372ql|@oY5}Z3Yvyl8UDrOYIe+lHF+O#2PO?%n* z^idG;a|A|4k7ObFqPv1&;ltqG#XZ+rr(O!`*LOvO25z*@wcew%2Zl!sr`KR13=3f) z3=3f)3=3f)3=3gc2n%6s5yG$#rrhLm&-DZI4<&VK$^La~kpKVy07*qoM6N<$f>i&z Aa{vGU literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/kg.png b/lib/src/assets/flags/kg.png new file mode 100644 index 0000000000000000000000000000000000000000..65111f5a01c89a04ae78d0c8246f743fab39c4f9 GIT binary patch literal 1761 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 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ky.png b/lib/src/assets/flags/ky.png new file mode 100644 index 0000000000000000000000000000000000000000..47c5580f516883c64247881138f4ea4fa6921973 GIT binary patch literal 2193 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 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/lb.png b/lib/src/assets/flags/lb.png new file mode 100644 index 0000000000000000000000000000000000000000..a2d62a8ee005f3880dee7f9a5c6d07618087a22e GIT binary patch literal 1199 zcmV;g1W@~lP)0{{R3U6oMi0006XP)t-s?HnZS z93=2TNbEyM|NsB(`SU-#eER+T{r>(L1gBJP%$)c9`t$quOu>b# z;>JO}eI2l63aMDZ>DAlv=7!a*gw(6{{P|A7hC91?chI5^t6Q7gyR72IDz$C}s8kTF zT#(qa9I#|4v}|a~m`T5bQp1Ui*RjLu)+DoPFt>8q^5qDrRy@0U-}LF)^5$>Nov-7_ zd(owJ&!Nrk-4d)_AF*Z$saJy2s`&l-%kA8L(x)b~Yu@wdIJ$SA-Mtm9U&!p)@A>pK zxOEY%U6k6k7_MPl#*nDt#NzeqEw*qev~8ZX{J%bFLiVdeJibk3kJwsAhZdpWvzG`Mt?+PC@r`#`*X z(eL0RvS}W$WyJ-d6;@Zsk6?%?$5h19H6!-~@H z;GNyPL0!_&*t8}RXEgAhM|PXq)81&4$p%riWK1rizM85A888wbAlgv2BUNOB60n&t^r z=@~43d}bDqodX~@*2p_AA1IL1Mz}&CxTv@UKq<;lZd(CVR#8T(YijH28?xh|s<8I5IQ>PBJvmja7LF2_&mCMOnUp;IGTuAbU*mo;WaR50(C>fBewLA z(J`QB+zovG6O&UaV>)#vYL*%@7mFMvA@jK0!XnMlWn4CEwzO<-0zoU;09GUEAvT08 z`r}f5WUYC917(}k5R$y*3;^3Z0J^}pyNCUQ!ztt)(L#=n@uQPdoS~r^s@(FF=cmj4 zl#r`Im|DKp4`3S25Hx+A){mFps2I4pNgVSbXu|}2CIz?XAmehr zuwbZqAspVebdl-`sCvon1Zn#U14}_30H$8ELVWu@>kbHclLuh>EfXa0-QN3C)koXA z`0z2cgaPuYCXi@~@QZ!@X7JNVw_gd75DAfxe;?6B-vPG>sOWZD1GxYI N002ovPDHLkV1muEdjS9d literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/lc.png b/lib/src/assets/flags/lc.png new file mode 100644 index 0000000000000000000000000000000000000000..40948b60f28a00c01773f92f46c757d90eb4f7e5 GIT binary patch literal 1085 zcmV-D1j74?P)c9$f996x^C$Hxc2;v^ZXcGJp1UVH7e*I$1fKx&zcRg1$TKne>By}Z13=3ongrlTu8dX9PXb`mKrXo80(&ez0l+su4v?`byCNCn(4j-7 z3LHLs7~n@TRt4YmL8ckxg%@6^80*CsUj)F9-juO~qoY9b^77o>-7CiO@bJjb&j&Cn zQpP%=Zyw0#(W6b(7&B%J01n7lpq~Xo)j-ZV>#XXr&OZBW0Ez~V$yivE3bJR<9#bvs z-MbgS>J-Dr;{V(^7Lcc(e!8|;&ph)Cz%dRRJJz^pkgTjMS6A2CV!64wWoKst95!~W zzygqe{`tpLC&Pyi2M~~N;8yl{9ZW z=0U5xxnsu;fGdWK^_DO4tssv+`e?-{*Iw*W?%TJ_r_VJPxm0}rvBw?*xWYx_#hM%g zlAfOK?CdOx4DRQcx~sPm*q5g4>^-Qjqxi_h#U&#n1Hhyh<`?szllW^9rUB$pjC!NF<4O}-; ztS#vv8#itgAwGQ0lWA)7gJ(U(*rrXJ0BlY-OsuzkQDg&o;DHD132wf^)$CVuDawyH zV4r;O!3O~pT6x46v8Kg>Bqt|3IXV6Jk87Y)=HA|nQimCPdvlD#TuDhu0eHk1u_B8= ze*E!AetA!K2ftBv?(@#GEh$u2ZtnWiW6h#>{Xb`{o;^EyGqJb{@rz=+m z4<5{QfT#2xYkLOBnl)?qwZD8t{HNYfzj(!yi)+`e1$au=vEKDVi4Ei~a-FNyzj37~ zSMI#l_3pdx26&1G^&4weJV<^S{l6wHZC->tiFny>VW9`lY3EuTmGcyT8cD)Q> zSElY_z3+!|1zO=ITR_W{qCBM)ZZ1>so}a#A%}W5vBdviawMZr*5Ay8X1bxLyDlSmM zuWZRu!icL9iwg7;>yI#1jeD}iGYQqWr+*JqbrNfR)Si@xS3-_Hx_kAN`?lV8aNi@x zd|y27|4NhPI*;%a5ArOJuZ!B-MzN%wC65>>>wh35+rzI{#e*TFWBrHL+`*kYX5(??v>m=q$NCSS&sRP6 zK_)`Rc~3Q_WBn1qU@8<*fDrfzRyVGmShqS6unPbLhyjL#Oc6{K2!>UMhW`nx`*aT# zgp(^#Lo;j|u}g+$ny0;P*6T4cJgJ6=TAj6291$fA1ch1_0xx}?y(EPIkhShCgz)J* zeC6kojd}5n8Dd%`c{zy2cu>Bjm5>-r(aG^4vpk__&nb%XH0+c>DV_tyqnV^ew`vp zK`@FyJ$%EjftXf`Meuqx(fp7`Au}g~b=oPPhuNURf8@TofIyT@M1Wt`4%#VekF6tl zSsceu0WZxmsIgda*ffT=)SZPWK|;DtZ0JwVCalxyOQduYLq(A@9Ay4bm=Kx*O(&R8 z)_M#_7oB{ZQFQ_UW7EoeUnE}rAU-*#qy!@nWZf>RFq`}E%j73Lsh8i0eKjbm8ZiyB z6a(F4OcN~i7!t43EYHKbiLbbOz9`qe>*nFgBKwJ#PL>qdw_Z1}ev7Lhmwn>3l{sG9 zbKCHy-TtRuUmlxPIEJvSE#ww0b!Xv%u(WBbTv6!UYW+YcK+i0yTW=7$_1yBcTfIHQ z;!O`Pgaho+`{!P9V#(mRoE>4y3mqGD`0C53jhiK1QDC+BUpu7^h<$v?XRo}ou*>F= z!W{16TW8A(?K^K427p&Th~4%m|L~Pn@S}|n=y~GWYM+O`?*93;TYRTIQ1U{5t+n1+ zG6ZgVAt*|?e^dg1;}6dJ{$Ye4ZP@AGd)o;7;)0`#zAps;FTWe(6U?jqC06`{fAGVS z56)lFbhUR>#s-#E{MIK4On{~!E6l$3VT=OAuoTBq{o@h>xc0QNlkUyc!C}Q%F*R`R zecbf$U^J>r8rJn6M$mw{brqBU1doJL25UCydwo0ey~`(Vz2-RG`L-*VllMEj}fR!;#vCe zr%QR!&Y~;H#Ong|G7n`8G>eedQB^-l?r!lc2fZmk*HVeNw){IWI)4qUA%6y}$0@w* zk;Wz6L%~|15?OUaDvYYV!@U%pwNnglL}>!7M=89Oql~_+FYaDXVg*U;)o=aZH@y&v z?6iuDcld21T0K?&+9FMW1#YOal`ZXKc6JdLJn?xh3a=+sv+r;xp$A3%%U}iD*gRT6 zye&i*VmN67O&8hQgBxlHEd0Mm$)cS^J3O_MyYhdv>4eS}my-!sf%U%(R(xy0K0ocK z7Q$evm?AU`7M3tOTX|d43U?e}WBoFhIId#*i|y2z9#vaj#CpO1=gxtR#LFk>7R=UO zJzHn-AVaUZLOCU?5@)qB536I1+tmmx5CtWxkd<;~YJq;id@i0<{_m_`Ls9Y&14RqI zvc1`^K+ZyY@pd0>h%+C6n`bKwt7~;2jQxEh`nsX?p9c1U!H^afl~N?ew0eQ1Mu7Dn zWD%gBIaZH0AE~Thj<%{LUsd!boT` zJer$>Bj?QH%okG^63L`)=JA8|b_8&;#~a*ACzg!S`nVS5&*80i=RR6a04*{Ytb~CE zSU;qNIUY$FreAiG5MD#r0SySUOK=2}dAtgRv^Bky$ii&p?O;AvBJmQ@PUmSwVKQ1+ zTconC6VcB6Ns(h-UP8j*z+kXaM(SaGpT>Mly70nM7VT!GZZS_GcR zY&XoBSiCtG8xeH<#rAu`$-H^o8O@BQh=f~wIP{~k(S;SYw@T+7W`GM!I>cr-VAS3vw8$W~CbnGIH<3m24ujKFcA>*HV!wt&s#ZWeJe zmb{VzVA03l4h6cu4Bbp4-mgXvmlLPr2v-rkq*8%scAGcvWe(vkv}QI~TfAtnKCDJ= zLL2A?O6{lBl0*&BUb}#ID4g{?2aJfOs+W1R9Ew6)L(u)@v?cBcU~7Q@K-h!Po9)5(gKNfXn^}Vsjw*coh&lJ$OBhIGadR{WcwN3~Oih*T5RB zNw9oGcDK{WeG&9KpNJvAS$yk=@Kj zGaD=juXhBoAVetiV2714r~@jpr2RU-{F~$ZEG*Yk$Tcp!VVR( z-@D}`TsN0pl{C1V*E2gQm^pj7SfGEI$U-Hb*j>c-9 z<|mUttPg7N7ZPkg8Fey}jTfGeWkW>DcsGn3tOJS8k`a2pN_6K7tX}`uMxqAk`bcdm zRKubF(FlwVeP8O^ln?h1?+c69o{3@mG5v}L#H+cvnvxKB!wd1OlE=ml)lqvp#w#|Z zI2PQv1O4AgBXQ`E(9?w3mQ|^QQnHys>P2?ZWob4U(Zf)^e(v1jl9+%-BIvpZtnX*h zYttuaM=*=C+WV1Ktn2HTKQ1S6UU+b4?6J+3>OcRFbzRW3BcDENr_cnwN zWw^V}oy(-p_i|g?uy&@nU6o*UqYoS6hL3CU_f-0C+DN@$6{M~6;JnNOHQL?Y6wu0f zZtQo3=p%gNfsuRy23>^G3P`iHd05@*R2Tx>5$Rl1a@2)iRkMQIE|~xk&DtqGC2hJ*(?2(?NV$}F`G<7#cWU}xoVWr*9}!J zlLXOtndCGLl}SDZu*w$T1~H-l*8mD|HB;Ih|C}>M(l)nlv!4WnTIduR2{w`00+Jcny-q70M(%a(Z?&$0B>h1CoFKh4d_4fDr z5jJxA`uq|%aser67(8|vK6ev1b4X>A#?Re|nz)Odx{;#3p037df2MhluziuTf0MJP zwaX1NaKOsh4<=*}HE_+<;?ddUue;FK-RBcDaG^|CF#rGn19VbOQ_%DF9IzC*0002p zNkl0{{R3U6oMi0005YP)t-s0F^@| zLaG1&001DL0F^@l0RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c3JVJh3=9kn4Gj(s z4i66x5D*X&5)u^^6&4m27Z(>87#JBD85%CMhW? zDk>@~D=RH6EiNuDFE1}JFfcPSGd4ChIyyQ$JUl%;Jwif4LqkJEL_|eJMMg$ONJvOY zNl8jdN>ETxQ&Uq^R8&<}RaRD3S65eASy@|KTU}jUUS3{bUteHgU}R)uWo2b%W@c(? zYHMq2Y;0_8ZEbFDZg6mLb8~Zbb#-=jc6fMrd3kw$etv&{e}#pGhK7cUii(VkjE;_u zkB^U%l9H2?la-Z~mX?;6mzSBDnVOoKot>SYo}QzlqokyyrlzK;sj0TMwzs#pxw*N! zySu!+yuH1>z`(%4!NJ19!ogww2>+9_7?Cj1;H~;_vhDk(0R9M69)8{vWaTLJu$F<5sgG7;)k*MswGBUFF-jbEA>`h1%(x1!0 zaq8vooaa8Te&6@^e9k@RUM7Txm{1;~2t_DD5sFZRB03K$KtwiGK3A^py8<$1(|dR0O&5hFu6jd*MA?1E`E}illq*4yCexHKHs-{an^LB{Ts5 D{t_D= literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/lu.png b/lib/src/assets/flags/lu.png new file mode 100644 index 0000000000000000000000000000000000000000..0937120d5605d0a126e7af5e88dec73f866042b4 GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z)#0(_g27ZqPQk(%kA+B#VE&u=j&#>^`RxUm- zprDMWi(^OyV=_ZypaGXtVWXg`vDRiTaS2bO#YPOyXFtiPX7>C6s$=kU^>bP0l+XkK DRBs%F literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/lv.png b/lib/src/assets/flags/lv.png new file mode 100644 index 0000000000000000000000000000000000000000..5447b3f4899ca586d680d520976835b328e76183 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*$P6SW{C@KnNU;U@gt*Q#u>Al3|GMqZoq-}^ uo-U3d6^zLT_}mWGt9(dosEjzM!NA~qpy6f6iY?MW6%3xPelF{r5}E)4h#mw0 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ly.png b/lib/src/assets/flags/ly.png new file mode 100644 index 0000000000000000000000000000000000000000..d898e4967b28b455a4899e8e5917f9ed5bf0c91e GIT binary patch literal 404 zcmV;F0c-w=P)}oRE-^O-)Vl@$vNZ^lol$0RaIX9v(S4 zIS~;N`}_MgHZ~Iz6P}))4-XIj|Nn-Dh7Ao3z`($!rluSm9BplFA|fK<;^K~ujwdH4 zdU|@z&CLe~2PP&ad3kxv%*>^wr5hU?Y;0@}4i50}@b&feZ*Om~u&}texSgGyGcz+1 zPa`9qMx8?GD*ylhs!2paRCodH)dLa(K@dREwQa{X?|-v6DaPrE`malGJrssv*f&NK zh++uz0|+84$FaZ&FNl(?s5~U1>4s@-wzk8#PzbMk{$V!=BOpYGljClhRk z>95z(V@fpMuBB%jWVBa9S1j5{F~UeI)F|7@puj=D&_REo;HcS0Z3w^6V!)^;b*+`>4bG?2uy-8+zlTG#9d<@)u4CNw?mh0=S(AQh3r@Kl| z&mb7+Bwh1B!;Lz+n{;#|-3?>h3}W02lU)o_oDDLa46+;zvKX%y;Ueu|*J#u3$!Fuv_4rj))bE;3otIaBtUKp-iD!rCPR32uYmXk6 zzfiW0cmBqE@2!^JjM2e|E}`u}vtf-O5mv<-xW-c;ZWL zn+(OgW1g4$W?HH)ssHdLSblP&kkOy7RpwhRKlF#X73g5jiTSbLZGLRBKk5qfHiM_D KpUXO@geCwQf50LD literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/mc.png b/lib/src/assets/flags/mc.png new file mode 100644 index 0000000000000000000000000000000000000000..f40ca3ef9ab345c064a1a0678a9ac691d13eaa32 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^DL@>+$P6T}9(P&;q}T#{LR`-Ys{Q}}KkU)ElRy!1 vPZ!6K3dUpw)}E%o5AvKf2hK}B?ft}{Rl~fWxySG=Pzi<Dnm{r-UW|+@{I)X4iz7HrKqSMYe6bCjOV%#y_{VZQHhOd-tB-+CF;sobS=|`&z=OdD_ZYA^VwakEBfJB{(L17RU7goUsW7Q#YU2n%5$EQIwTjx7Ld`oN3bKcR!L z`bt230ih^LWL%8OlychR?fAy}eq37%lB{_gWyP!GtS9HWr}{`EtPgQ(0|n`0BGO?hOTVm;ahJZ+@AGn_KLOlH;)-yD3p6BNfP zPRw=d&vseZOnY6pO=b z^ZYC}4v^j)dA17#Vme{=`VK4=wt>u@jrhajh6)DT=|zt)3}EYUSfXwDbcg~g^$?C` zX*fH^!LTe*;=i&27nwGuGdj5X zwdwN3acU)TT9rvUCGje)T&0#wMnjr@WjqsOC|c<$m}|@76pN`QW2GZ+s3NsLTV|h_ zI*cw++1+Al^F2d;|Q5-9>_GlkXS1x0kKxraT1)FDQ+xS_u~%h_C}Bu^f^{jETzt# zZ!1}IIz@R4Sp#CNXd~2$NPiXU#cq6H!T-eE#Z0WlKgNPIqa;OFcY>)SN&Q^X_&n0O zE$-MGP8-c7Q$7LZ}8zQJm$@ujn8id&2mwye)jl7ttWSV*uM zhVj}?6E`0v=QiVGtdbP4brPQHtaamwvJ7#3eZ}!PE^o2ym+@P5)3JFB8>e&2!2i~Z|b$3#LIm;%hp(fD~V!<&`h=Vjfd+>rITv=B7vJPe%N9Gdx8g++w=h8V#oSpS< zt_Q2SfQ02(5zfSvqNMX{Xrm%!AXZv{I65!AB1boSgz<`2;?@Zu0Mkedl!6sJPO%CDEa_I-3?^UKNNO)-@c1Gk zJYEo@+~3Ms*kV0UOo82q98H1h!QwCXfSNp7ysHj=v2wi4a)QJ{hfs^@QZ0TocyL}L zu|3tHJ!LqY6pV4wf^&iQHiIewsa#dT>O}G|rp%~dT#gMh0(r(I(k`w5-n@doN;H^v z;AB>$gIb=id0Wcxcqd~x#;(nx!YenmlN?9_8Fo}y@nc3pc*I)R@^*Z;y^Az9m9VM@ z6hzX-=eU|_$#teXW_z2ZxtpZAGa=3Kg`hr@cz+AL7#x@djxWIX>JA*}WrmR9P%+v; z&yTGRv8EPy7;Ex&r91htRaSMvnPs#T_E9Wp1wNQ)oHr4YK`gks6TngQMgD&63374g3J3j*(9crWm#lrnVFd>$ucvAnb%=nX88H>v&E7j^atHnn>^TK21QkE z>gky(eX6IYyJh`s^v&GAQ7o}w{r#|FC#cq!U>n}=tg0MGTE_cgygk0~DDhY9Kx{#0{Sg?d& z$NhmuJmwTHWy?2mq-$By)hy{&j&vzoDs=qe#NWgTznV0#aH-O!RQ|K6f2cp<hDHFh4AD$tRHx3Rf%N%EnJVK3>dsMEV$|l?wMV;z_5WjEjdD#;2W7 zDgg=xQobF=2CUn;N;wg3r-Wsnm>iZ?N2gRycoJJQc+?X*%!U@3u^ zWnNhGKUPX|^)6cLpoX4svHPr0=m44tS6cA#=xaX!iK{*n*QNj*e)97^ni&1{@1*0- z*aLR>F{iat;ci+fabrQ#!s7iOg#%ux+yhLJK{nh&kG;v0_hd|r&PdYQXc3$1xKlXo zkQzv}l@?|uPsH`T>7#G+uz4{NyH%|8gj>Br-iM}zCGARAs|c}*K!j4;D3BU^n>X^z zFQiYysCd98H+}F{WS(M+aD`+G8xWJKen7aGy;s z&Q)6|y_dx`kG(cvA%qJnK9%-n)Zf^=A^*bBQ-w>9T!-MxhJp(X*EeAZ2BWX?#$n;y zjP%gzT`!gr_h*>*G<3|+o4tBFrFSq|7d`yUa2CGMfzn5=_AJW3wfn@GK+(ovGq>-= zsRe~aH?QyY94;5DNf-!)P8bhA;lkaN)`=Bpy~T?K%^S1aGxY$4gG_EFhaa(eH$C>+ zAMK{)GcNh0W+!^Jo>kw$2pjFEQrGeQj}G8$l|Pd78H(9}ffj7!Y7A$5RH zAvwTK9C_i_x*55ZO*zoAprEMf#s=5Hy7T7`-8{Rat90Fov-x~0qxaCmFzcc*1rw2N ziAU|`uMOp*Tp>A;Uz;-YE;|=%Nd%yw$G&fy*s?1-zpmq2uCBj!ZcnIzDLcP4*u(~| zuluHngJ&VkiFIW3K8J~zJ}LTHVxdDm=HP!57qZQeYdr`<$mW%RS81UtEB$Bd=l_9J zR{1dm1EgJ%0Txq2w(02q@oCe{4=a>8Gu%l}{QO;f$T?0$p`-YjyN9~PP|=t+%t z@taVW09_)A*Cla5qXE zGWGzY{8AscP$?v(_N!R$nhu9SE!Tlbu z5}=TUS-0>1v;@TtWo@LaA)Qf*8l*mNa2=8V*70Uo?MH=L=%}<>)^w w7Ay;v1YS7HwO7_RoVy-&d}G zt7*xgJazTB?YoVtS$F#Q65KAumvlN#XZ$v*z{9@~(j*u7OkTFVg6mv{PhjuliEfUB|8g6)H;$B$qCn)^bkfg(>;o)Y@|9H_$W&Pgg&ebxsLQ08tN0)&Kwi literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/mh.png b/lib/src/assets/flags/mh.png new file mode 100644 index 0000000000000000000000000000000000000000..e7f88ed230deb832e9bad60b5b29214d2aefd97f GIT binary patch literal 2684 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 Ici8p+0eX!qAknrz#q^lhueix!!4 zf@&gLtu~xc`g2k2%|sCQQ1`NKpi0(~Aiv;$zka;AA|f`88z^At>Eakt!I+fdz}(Z7 z!Q{mBLd%Kq?P)_^pd6FJ@8xFA>zn0W14Uc|r`%tp(KTtO$ktx~m$@O1Ta JS?83{1OSNOH+TR5 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/mm.png b/lib/src/assets/flags/mm.png new file mode 100644 index 0000000000000000000000000000000000000000..09363b3f26e45ce29e8bf0987e8ec5f9e886bf4d GIT binary patch literal 953 zcmV;q14jIbP)1^@s6YD=Kn000AkNklfAnj_a>OVp9886;c6 zvfnq2FbX?mm(bM@Flq$ z`a_Xx9<%XiID8I-Lw+ZJlZ)4ulR+MCco@-mxZxoN$&?!=Hy|1tCf74aCOmrMQLuWg zh=#>$!BHEJWRP@wf8BkEmHX=MWsq>5u=#lWI`%7C3@u5ick2-=dY3-g_2iu8+?VGw z#9#L*B^$rJKu&!@gUvE8gF&JC2MkH7|pB8ufnKp6zO8rI)bapujEcW z9_9XD_5rD8RdRa^{_EtarYE7O3X()-q+)NuAXk)Kj#P1Z+2st9tY7tig%lB(^(BKO z>yTv#sbbJF$RNphammF?>hyFkQqA;q543#E zy2ZVYh88uRdI@61`SV)1ep!oHF`jZUw0hl|4Ptxi6GTI`SYf&Eseg`Hn+oY(nUeX8BV@Pei!-JmJSAqN5cu{BP@yn`zPOGao=OZ&)D}k*gyRa z^0y&TRTz#xk3nM9_R4#qTg=U4>Ds$uo+E!N$ArT6^1BQYtKNndY>B&|4EiI^hwVC%IC{WnJsuK>lh@G@*bfWjIiAM zWV+XqJ&UXr>3xYojOShxw6{p3vQ}Wts~IGWltCDTG6;iE24N7&APhnogzEHr9o&*Z z_sInK%meho2KB=Q^~44AzX#G&BGOYN(o`b>QJ2(RBGp?V)mtLfT_M$8A=Y0Y$Tln1 zVIbFGAlG9b$Tlq5W*^yW9mzB+$u=t6ZXDZi9NTdl+jAS-avR)p8r*Xm-E$hG$-7~p>w;D8t5ffwO~7UF{z;)fLDhZW00C(J)6 zfN7S~Oz3AsR;`{4UTV!I3|GjVUl< z4ieE9Jr=Q%2!*kTUqNzE#5}Jc&%6zYv>s(h#BDGFk-&FrfieqShY}Dmr57z*r;eX4 z=-`{5NW?Ee5w7nIPFrBhc*_{G>0C^SyeEqD^AScwT5dQH?ZwI)L`$F$&aK~AibIhm z(?=$dh$u=DNJLD3puKyNIk7WY=~(*lHijMiLm}zCni-rzBCD^IkA$L^we>h;_feGe ziI4tO;*kHtL@}TCp3Z(jPZHbyO9VZMcIT@%8wnBB)j+?l<#X>3$B5@fzcsWiv2W;@l8!x(K>l796#$$f5%Sahfk7r*c9*tVw Y0gd~J(VK#z_W%F@07*qoM6N<$f*y{2wg3PC literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/mo.png b/lib/src/assets/flags/mo.png new file mode 100644 index 0000000000000000000000000000000000000000..4a731ce45f2c5ef1e6e4f6892dbbbf89376cb6a4 GIT binary patch literal 1517 zcmV0{{R3U6oMi0008GP)t-s0C-;e z(G~!BUjP69C5&}En1pMwqJ+M&mdCx9$i1G-!n)ei!r$1-^Wyg}$gL$$=Gp7#3VmeT?C9O?>fi3`;P30< z@9gC9?&b0C=JM|ie`f3S^6>Ze4u5A4eOdVX`w)Fu`~Cd<{rv%XUle~?6@OTPyss{h zdxEAoFOhr&dtnxUScku}7=c$blz)q=Ha3e-jHxy^j82WJHIAw^kgGM3t2G&bS2>n~ z4t!c0hHse2zMIOxoXfyFn1i0MF+7b;0(o5>hj2cQOrp-j9*A*2j!ZzBhNsZSL7IoD z(aEaP$*Z+3M4XANwJb%QicFx6276)zd0n%&E3~*PwYVxFgjBb`=nH&XXPrRa?&@c+pJ=b36MtFa@a^O9?P{>0Yo0&m z${Z7dYUj!u=*k=E^YQA-8*H9FCWcdRv!y1CcJ=!C_WJpDqC6*tQu_S-ccMFaxT-CP zQ4D-re7dX@gKL7lu!E*Jzx5RX00001bW%=J)WKNJs{jB3<4Ht8RCr$Pm_xfOPY{Q1 z&&1}TZQHhO+s3tR+qP}nw*L4UH<_87M3{rnETXV6Gn)%6 zF+!-92>Wep_7O!tLPoHXC)*L47q1El)fiTtpf2Vkv~w7CCC>j}>W|lLB=p~$ytf#5 z<3HS|!g*7w`29^kr)v*}Del};V3-p8bUDt@1dfT70LKOXrd&;Dkt2x2;syG;gbWG^ z#}8NG$CW6^PVW!&-U4DJ$q3zbCV~&nYFA6z18^VmI6Oco8Dv~>FAq>5X22UKxHT9< zwGO?G1Cfkinz?6-xTJ*Bm`$}-W7CRZPglvw3Q|&eN}#t3GI#4kQqq)_11`C!Btta6 znUpl2h$cJI8(OqZ>A48z$_+J>bS=z58)`cZGv8DW8-SBuN)n ziqrkvtbxX5<;2b`xm?KeWnEv+E+Zx75i4o}9;Fms5oAU<`2$FJIE6evqvUE6vG3Q) zHW%O;cmNW{cYKsuiAWt9`|7p5flm;75{qk*%ZOLGPAe8<<2%dnaVYPBkT8Cl^Z)MP zn+HRTOPcp=6Gx^Mgih3%9(PMyUMa-5!owunE~I=W6>krpJ9{LFtiPmsW%aScfvy$H zllPMy4-CB?9Y01;l7%hUAjA+D8>NRsJ6r*DrA@Jvu7#XtTa7H2AjjIsXCc5|N^Xa#gVc9_c?EwWXp(V70mKcIR)Nbiu To=o*r00000NkvXXu0mjfk_QZ1 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/mp.png b/lib/src/assets/flags/mp.png new file mode 100644 index 0000000000000000000000000000000000000000..a7aa3cd2f8f5bce95434d769a9513dea57844f6a GIT binary patch literal 3726 zcmV;94sr2`P)s3_RZI!ghyww0B$clBz3;>RYtUTJ^oV_4m5(JyFWl4{G_sOv+v#_Ay`jCzn&-BUs}s zh4wcBIB67YKy-6$R%yt(GGUt7)`W8Mu*BwD+Mhq*_Rl=NYbMO(%Uj15&@mTt2#A*A z8|tj>Pr9{zCD>3__IMZtf@DF^oOc=4I4plXo(A`2J}LZL*QLx04N5w-`L5TLgx^;e z6TZzRU~&mRacvKITV33FX4R6Dv;K2#2Fi5lo#V3;cYR-hm?`l;s-`aPymwcan_nO; z3Z@Cawqw1Eu+TgRobDExez&T#vq7b}GAHin&noY!nTP-6+8t^YIdpe-KO5-lFFmZQ z!ajTUtX@^O*nBpRpSl^htgNi8BF>I_^vmp{^QzFZ(nGE{Ws(M@^ZR5L30wgL&3&g} zEhF#(sN%?|!kU7P%uofx!>!(VdfxG$vi*K~SZuAUbk-HF);;RcYPAFP*ZS4W=H})k zcI#Tb!rs=_)`6xFoqR`2i6q5*eUbUMa*Ho=!cX`0J(bE!_mC2{lIY`b{C5G? zMDuuIh9aA+x*ekmgfoiq8{~)Qre2=%pgz05#!V+bGx)IesnlH6)X2*gw`uAUg$39k z*45}J*BD+XT_{x)78gtVs{GqD6;B>?56FK~acpDH9jV05$iQFdX{~-*?ewIAXdgy} z-~`4EYc+`<clU3!kkiPsa13k+A7KyGQE|it&8OvTzN}Y;j zeTGXJhXyhv1U3snr%uB%H@Pr2yRzJ)xJ8P}!AGr+q?qPrt*%2Na{PpK@OM69X>abT zfeu-sFdu^988a+6Jy)je)I1_Xi&HMgu}*9gkydx7FYQ-4KdgwTt*wz&*4dJI6Rm_0 ztl%p|3Ft;sGaC6@ZbKe5@TnP=Bh-L#}`qPt>TU;h9uf8LdX&RNfqMsBL z&q~Xg42w71lybL{Cr8qaK|oO;+mgMb_~z?@5WeYM*{pWM5z3 zS)T+z6S!Jn%UQ5EJ3B{TAK&2{$%W)fbRB-}9OHwv)q|_7ukYySxPSlt_3i)hUc0!Cb5T#d>w3z%Gw1R4 zZHT_=qpi9x<1`Zj!C{5Q1ZzBkal2U2SLr&SNuXYJt07Lso><*c&F!lWtgfzEX_x$} z{{>BPaC8}+RwX4R;pFg9SihJ#L6FQ>cKP};$HXgzl_uzyukk&%(!p$UL25}cyScmV z@j)+^F~OPyPu6Oi2YZ$E(O>8PHTUw?6(?PHmz9;`LmA5)-{ck{nC3Rb5jt0VfzKt8 zNZd$n;H{H`(}L6P`c4GB#T!sZ$0Y}v?E6MwW!kBI-1m4uAgY4EX+{HU!6mv>RswuW zp)awR_%#%_3+8i5d`CLVQqO;mK3f`R_Q^z8EGc)D@Gnu=kHW#x|_KW->5lO6cd$7GA`RV2*aY?Bk! zz+Q{sAp}PP-VR?>R0LoR3=G`5c?(Rdji#jGML^$eqf?4Pq1fy2tI4ll@vYCP6kT#| zOI}eaSPF~))-Dg)(~ioakflIeVEcVcgv$+zzfHh32g&zqf}|Sh8m@kxaX3x$B#19=)aZ zesAkj(?AAT7RNNK@mA^X|7594RK0nNnP)#&1n%gr2uS2)fb5mw9Y2GTfzbh7ABEN5 z-yaqd_M^G`TTl9_C0*6jl%Jn}>c~tka_`{apsKR%7XoXn&#YgF^wJD%Zg^u+a(w15 zbIOu@2cL8j6LLng!z;02J3Z;I-%b;Q{|Wr(!Gj0SUKl{X5Cp$BZol0%`BOy9=y^>8 zY4!E>$Ih;~dhT~!d#O^Xv)XL-Ot$d-RQXBnRH24Czl zohefMpD+Op$(tOmz}^KJdZn7Rn(}_Xeui!H#@}}-fJ-` z3`o8{Qp^nTc!a^F4J)`5l`*`rl^c48#pWnfaUx#6=n`#guZGT45C;Eh@n2_bjwC0B zgOw{cH1Pl-?6;B99Rd46Mw){4OCmBI5`Gv5K!3TWyqlB*>SVQg)J>D zG)nk}vx|Q=U3v9v&UK0iB&NrDxU=Fi#VP>y8+5h154^H$DEA-|i`TmAttQMtQ?$*^ zFVX>J9suaYPp&a;8z_05yUGTC30NpR-O(E_EZ$@B_pNh<*QoiR{x;TOZE|J^Zu7R` zHXcC##*Xj;Q47$cf{HqQIVKZt#*6N#q(I{9>kCp28ntHh!v>Xl21>6bI>w~`4`Pi4 zZX3emycG%E-SY61AKN(cS>}F;o3Sgl!q!~3J<_Hf`pu#u*=MLX$vm2SlPw-~qvB%Y zJl#DC>lRo9xtxeem_1T>69V$6>LODVBWWfOX!V ziYA$zu-nUw@aB_Az(znaudYG06#wd?29*1*MhkvwU0vPPf3AWAJis)11K?s~Vuu|u z-;|s;6uVHYw0t>$)!KS5!R_oZt8KM)wV-kVzn*F|nbJdkY*0q_z2)6hQ=Q;)xJAA zV5(bm>N&p@Gb<;+Mc)mS#TLSYZqal8bbW4#(=m)JY59nvRmhV)kF_>yfc61!%dDb} zuWpFCnhfeRHN|)69!E-wctakOS{;?bnU5c_k#Q*2BFmU@P>O@2vjJEj1vnpiV>~8x zAv$8DMvvjGw~YXksJ*@Y;ll@1!a4OEz7OO3MpSyB4>266mDzygmj{xE4_#-nCoKz|m z_$Oj`qU9u`?R8k`$Z`x$0X8TkyHsUbH#JrQwFX)a?9n+YZKxWEV9v9+X^FMer&+@{ zP|6?55o7qE3~|w)I_gsJf*b_obD&8O95#uY4uMjPyNhN8fqT1927<&)syEN>_r_XT zS63G>PatO@tlU&d`4MXm8!Hmd|v4B-Y#`j zRh6`|Zp)PnS%F1uBM4LT0?^;jk ztV=?RK#Ei1<;n2dE!@@|= zR@n(0G<+}v2;aNefIAIAsczJOC9JGeo=x{)!q+5u>~?T)wz9M`pzdI;bg*~uC7IGp zS7rDgkQEBR5&?qk9Jz9#BmZ4)?FRj&(5v*&6#kG;uTgEO%FT6bd^Z7ChuK(I0kkXVi*zCoZS0*-Te)tu@SF*Y|8P~s_TXifydd8-BR`H!(LUs8pafYXATM07*qoM6N<$f0{{R3U6oMi0008eP)t-sAVQAA z%;4YS@Bjb*Bt(xVN0E)5#iOv$`TG3&`~3a>{{H^|{Qdsj;_meI`AB1;EKHOmLyz|O z`zT0~&D7;bW1%=znmbsVJzAVTTAe>zok3lmLSCOnVxb{Ij!9&qP->=8Yo=9hsakTY zT63#ib**H3ux*01ZiKabkiCDBzJZj#f|S37m%%AXl8Kwcik!qNOOubE#)p~0m8Hp- zrplhJ&Zo4}sI}9ow$!V))GbVuE=`rPzSu8LmBY;7$k5}FqQ}f7P%+~MsoPnP57 z@#N_7=IZk2>htUF_3ZEU?(z4vz}ffs`}q0$vAox=y4L*s{USq-G*Xx{P?mU%y6Non z^Y!`K-|SCmrDuJyB}R~>vCxyF$kf~ErnAyYWut?Zz*lgoZ-ut*@b;~_)$#NAh?&BP zn#1+?`Y}(Ivc1@GhPQHux3iJT>2->^c8j^2s?68j>)77woU6>*;Ow2O%|KnApsvr} znt@ACIyd9U*H z_)TY|ue;Xu_WH2A*G_4rW___kU!SwT*l2&U`}_TAfU~#3+G~NdxWn7J#N6ub^zicc zmZixyRGF)|)U3JHj-SOhRhf{W#*m@MYJjtnqR4!Yyj*mw-{kMKzu7WTmpNCOOJ<{h zlfIg%%(=we=j-z;N|R!GuV{X00003bW%=J z)bjY{8lWQp00fIkL_t(|UhUb_vz$o)#^GdtLmb++ZQC|t+qP}nww<+Y+x!=HPiju3 za&hMCzR6al^4@nn7w`9WP1p31O5bP9=__~6TPAIo(|1p{3g9`z`xUx~`6V3=6Ic%~$RH≺l@cX zU)!dKT+s_M?!*>rSSou#j`oX!R%K*#$Fy62-UDEbL?`bINuJyP3;gwqa! z$ax){8!#v_tuCud8!_0?gyuZh5ZhU8Xwi+?=^76mArh= zC?UQB`WNzoo_dV6nv`dy$>pFn$(9{F-kL zR6Bp>WaFCApmyX3;o@z>N~n@A{<+1&i5Ej0<}J`crKcqFcC4cT3bTcf-P?iI0Y@cw zvatmyPuw836G!-ET(s;?94g?zcN0a&IEtaJ@?)F{ONzu7zYCa^o01S5C)LSHFcs%$ zBi~pgRQ%YJ0APP%v;@)_Qw;$3cPtV>yw!dY7dF`gZBn1GZ9vTUHa+l`@C6wiVhuB; zFUah0uoggek9{R=b%_DkE76IaPjh13x)y-BN{GX^#h9a?b5s~#k@8#AOM9 zv20Ds$m^NnJNdd4z_fqC!9l0gN;|PF07F&m=BSv(@sX!pL=pE&s7d?s*MwM2d|2Rd z1!M?NZ=fgn6U2~b0X;o2tPAQ5aUVG$AYeXVEJ%%A7_#cnUsaW`Pzh-t5xOyG8&E&x zn-R@3#vRT(V2^2VZ=E<@vN8bNPw;)vT*HsaBCp@T4@v--y3psr&84!rWBK(PZKJIR zFzuXDSb7m)wn!%#zH1VU%S=+&9Z%eeEw;W`U!pgK9+xi{sr2SZET^d2k!s?002ovPDHLkV1nNd BFpdBK literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/mr.png b/lib/src/assets/flags/mr.png new file mode 100644 index 0000000000000000000000000000000000000000..cc1960fa9975cd73c300029abe8620f2504b7da8 GIT binary patch literal 942 zcmV;f15x~mP)0{{R3U6oMi0004ZP)t-s%ql<4 zDn27vGyq~V8*MIaj2&!?9l@*&z^n}yYcBo602XU6XNeyF!~kZA9|~qM3}!LAst!ba zCFi>Z=DP(IYA?2^4+LW}0b?_AjvV>H0dbBT24ylZbtyo4CNp&@T7)54gds(IB{Fp> zU4m={BPCW@CABycQtkQ;N3 z9CVHxb&nikhabkS3p{xzJ9sA%XfV#P3eT|${KEmmtqj7f4CT577;7#ia4ZL8G6-cc z&9Mrip%bH^5=nj}jhGh#V>3v7CBCZ-wWkjbXfO|GFuke`GaRv*TO>OsYtjCA|j(W7Zn|0e$jFy zCRQeKoQso5Y>eede2`2MIF~4sq-4vHlvJ6dL3##c%ET|rawI!PM*g|v<>wbrSR|w3 z63da&G8vV>t_YVZtEy{cR9j~`Qcr^n8k=;ksaXas)LV|U(k6o<C&@w z(P=r-4NZE6An36i>3vOKgq{@9&p@x`hz21`PfCFyS&y{C@Q9u;G7N1tBBMawm>xBr z2ejCTXabnjqo#lf*@;X8%*^URvoip5wj!DbSXk5pmKFe(WiPT)4Y0bVd#$YkRL9$l zXr1piHbZ5m(9I3LTbJF));8xd>PBQRQkTKGuvyy?Ev<5)dS`bpLgym(c6X||u(~As z5#{f5t+4MPGxMOYkZXte@O?|9JrBY7sGtzsUKvnA^hv+geL@uA1VGsv1%Ojc{W zFilPV_=#)%pO3w@bT~O}t2#TYYCApobr+@wuqSQ_YRI5jWz5ud@Do(IE;1 QegFUf07*qoM6N<$f^I93x&QzG literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ms.png b/lib/src/assets/flags/ms.png new file mode 100644 index 0000000000000000000000000000000000000000..e51480c7e188147cdf45a2046241ff0725d01614 GIT binary patch literal 1473 zcmV;y1wQ(TP)(E_@|_PpG60IJk6$E{kyCSs6bU|}#(wn0s?o?X0la}^7N3=0dN z3CgQCAJi1ftfPMrZ#M=R78X8J0C$&Z2Y)riB7fkM;bE0;CJGilSy8bn2on_xpG-AY zg<_&&;giK>98-oBpLMK4F_95%Ijtg+oO9=|KKl6T^_yd-pUHMSlWc=Ie|q%f=d_h! zy*qpHnRL5+`%j<0oWJr2hE@H!YKrykuZse#zb4h&>T9cYL&{UQA>kCV~qQcB>wLjM!|9jl44*9H=j}wSP)&f_W1MX zFF&UNi>6n*4m=ZYgJsmabC*v%{^lCa(+k)6X-AY{ z#iSj5{q}=`zLqU-tZ;jN{#wyrG2&v8F-gc?Ur>M$YOvJ)^VP$go}Ic)n@ep5Sb-9J zEKDZyVMX<`A^E^m(qy*cd=#G}k2PGH>ycZCpiG`2DwKp}3lTrF7_l&zivHH&FUbB1 z%co%H)`PpXv^3Geo>TbKYWTI#445g8Wgj5M#=>PPI#x-O*=FS`#Oj%q>zZAlsi}z; z_d={%t5TMYPjI2M1S~r&EPN(>tdblzr^yM|9N@)e-4lobQD z+dDQ!?Am}uoQ&Mq-?4PUGgf$H(Fn^sGI8TTtBr%K!r}Wss{-3f$2<*Px|q6kuI}B# zw6T@OBqvi63&I|15!K%e65Y=f!W!Rxj#C~1+m4K&5muk6JkI>VzY{>DWA%m82rOM~G{n;a zq)0DbuRpMYxe;0o*)+n^X~c>6Un&I)vTd4P)^y!krW!WxHpFS@Rtpl^-{@z9z!8mD zVcTH@8eu^uuM)W}86)qtYq6e`rB7VfU1}m%0?T$}WwI)vr!hB81Z!{FVQJK72{QNj zO=v^GO6s8>>1aZnfQ~gg&oj@Bcb_o1`j7t`cn7%mpBV>zX@>>TZOloK9c0h$Pw^5B zxA7Wh%^G5oIkxV->_oWyZyaD592q)cg%Ent6bk~EYR8~$fpL7FF)e_Jsy56jZJ3qa z(upZ~`#X>4LVH?ck!dtwU3l{D(1>8qS$$)AS0Sas2G??2IW0{{R3U6oMi0003mP)t-s_}$>o z6f6J#|IZXF_qxLKr?UO&?8bV6#lyk7u&(*S%g29*%*@QexwroF^T&IF_NlY?;N+x? zh_9xgz`($}yST!^z{bVFr<;?@i;wZEw$yxv&1-e7q@K98w79pmtfr#Ay}7luw5_J1 zu!n};b%Wo5kG8e6xU;X8iGPuUf1;O=#>T|3u&&F?$-a}7%gf8MvarFvyt1vRn~#N; ziGZ}PthKeW#KXe4xVE~rvbVFZqneVbqMfg+rMbDc$j8Uvf{)0@#>>jd#>B(Ax3i#^ zke-o>wXUnl$;Q2pk@(5a?U|@tLLl^768WhO(cV zu&=Ji#>T|Lz^IIf-J_|;euenI$jfhezO1afnw$LM=KI;+{`U9dGCq9(0007XQchF& z)GJ7^KmY&$#Ysd#RCwC$)IAG<0TjjY{~_g(GAT0hJ~MPuex*vinEv%?n%e0 zBuzpuzCQ literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/mu.png b/lib/src/assets/flags/mu.png new file mode 100644 index 0000000000000000000000000000000000000000..b41654629ebbac16a658d11ef503780ee891daee GIT binary patch literal 166 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 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/my.png b/lib/src/assets/flags/my.png new file mode 100644 index 0000000000000000000000000000000000000000..6fe220e9d4d6ba99b188c08689472b9a300c739d GIT binary patch literal 1024 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 IM6N<$f>VZL!~g&Q literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ne.png b/lib/src/assets/flags/ne.png new file mode 100644 index 0000000000000000000000000000000000000000..fa8859a59525cfcd2572396c5d2f460ed5e30c62 GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^DL@>?!3-q%`VJoeQXT<5A+EgZwI5`v@@~)$JeK|- zi0wfL=YvqLCs~@$EA5|GIlOG~eLW%J^~A)ta|+(hE&Q;m<-@Ah53Ae0Upe^W#<4%| zU;h91_y50t|NsAg!ckugG?S?$$S?TTzi>zUZ9v`$PZ!6Kid%25Me{W)2(%{N;tRUH zYRc&y|L1$clxyB?b8|lj<1wr2Pp!RP-KQVZ^`njxgN@xNAv@W3$ literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/nf.png b/lib/src/assets/flags/nf.png new file mode 100644 index 0000000000000000000000000000000000000000..3c94505b3541d8b0979d732d601e2bf88cd3a66b GIT binary patch literal 1313 zcmV++1>X9JP)>JMi_=i8iz?CicTVnPbiL5DUVe!l3Fp7TQrniIhSENmtsPk zX+@oDN}z8{p>a*2aZ#jnTd90$u!wTCkAAzDfV`T8zn+Z4qmad?pUtzX(z~_T#L(v2 z_4@bw{rvv^{$s6!`uzK9v54yQ?mU@fKAL3(d^iStIZ2;x2YotApl}I(I~<5gPor}m ziA_?ZbyKBwRi=1Wrg&GUd03}MeO{`6V5@*)tbz=GK4h+hWv+x~uZ1Iv zP$!L3Yq5!JvWji8i*B=wZ?lYXw2lpcK6AB@bheOow~~0clzO?9e7cu?yO<7uKYzTL zDvwoxy_&&J`>&E?n5<=8WnUE1v8-|pt=^X(FX zLiG9eH! zq0Y2Mo@}YoyLq{kt<=6Zb^7!>VnPpU^clP@D_xt(y`}rG(NkE%t zaI}q;$E%jet3jJ+|NsAy$J0sx00NCkL_t(|UhUY^j%8sG1>m)hZQE_zwr$(Cdu-db zZ9do}-I>ej>5KiJo0;_jU$T-)stQ}j`g2>cV$1x~$bvVJ32z|Zynu8_UXVwg=FAXB z*3vj{Nh1^a%>t)mjwrHv!o&^=Gt3f2e7jBZ(AZ=fNo3TXUz$tpG-SqwmEBZ5@K z*^I4i#zUwDP@K^{O9Jt?Q$d2dN)<#3A;49&5#|Ko)6o3lfS5vej9|kINH95s`(Kyo&MAXYzDRXoq3k6C! zyX5R5U=0y1vn?~l?iaIDYA5lW~3vrP!$0L$B3Y4?<;x6RM%J>Zh8^txO1dF zg9mmd3q!yPlmmr2shwWLbINc#U8Df2*TGu>I6BLv!I?=Hoye$~Ti){sprQcqC}5p| z>IlB(0gcG(TMw5v)oHyP?{xrxv$jTu*+m=TUyOz@Abkjq>00000NkvXXu0mjfiyoud literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ng.png b/lib/src/assets/flags/ng.png new file mode 100644 index 0000000000000000000000000000000000000000..fd111eb07c92d0da6ef57006c97e25f2ec66e21b GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*#0(^_M^DoQQak}ZA+8MVfvc_`{r~^}%Iil~ zy-Vo;ic5RCIEGX(CO0sy3>DbGre^Rd#Vr*A8TefIH4cfaItWz8;OXk;vd$@?2>>Yy BAOrva literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ni.png b/lib/src/assets/flags/ni.png new file mode 100644 index 0000000000000000000000000000000000000000..fa964780a2fee279d86914e73163cfb5996bfa02 GIT binary patch literal 762 zcmVIYEkVdzSM=;Xa|ENBet9&0v~SQmm|2`ujz;Nz^CxizP56rsL`FL9tja8VneI2%P&q8wp@oqJNa` zctozDQ!Ee_MKR-O@wr{@C%GVc&ad=lp!s$Kp|)Vv$X=$kw%{ z*S_?y;c$|ZJwN|mS-&~SifYqmUpD_q1Fw72ubbm9SkrHrlW$t$FS;{tn}TmfMi#)P zwAWR{%b!OywP*C>ZT6Q#>F1{tFZOANm*IP?3$)8GGdC4Jc~zoDt9L{WdTzs>l#ZI3AAFm z?N(D@N@(efERlLYNDFMWQ#{QO(VJbxFlYcRpObh5ZXGV|HX95UM9W5&h-30VMn=AJH&As)xyo;GA;P!Kq>VRHkkP68u$ z#DV=S*Dw5>Wg8ixm$os&>-6DIhTTVlqWGruM(RwvbclD^gQOG9m&Mb7Mlg7~`njxg HN@xNABD^|( literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/no.png b/lib/src/assets/flags/no.png new file mode 100644 index 0000000000000000000000000000000000000000..b7a42f40c043aba5f92f6d2e81501444c4be678f GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MW!3-q-@D=v~DVqSF5ZCwGy1%yX`1|bHmE#wc zoGMKNTE4cn0|kE{J^KIu|BE-CFlb~**pz+i?)kA|<=^Mef1khb<=c-F7w?H%mzI5* zeg|j{dr6RA@SRV;e*gRT%AKWp9Z;yi)5S5Qg7NLOMz#h6f%cF81+@kD{-10%t6;*4 zmtJo7j~leh-!QvenYOQHv)8LlN|8)ETN_}&M|^XQOHikxbLu|lJ@v}Psryd6KFyqR vrMj`9!KCWZ&Q|Ga$)9VF2nxVJZ9~rVEp@%#pC45N?PlbP0l+XkK&w+I; literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/np.png b/lib/src/assets/flags/np.png new file mode 100644 index 0000000000000000000000000000000000000000..7f2ffbedfbbb5ecf4a9caa610ec5bae111643a2a GIT binary patch literal 3225 zcmV;K3}*9*P)3OxO|HKL^b*?9QBcb zOYjSaJ{T9aL4LJpbzgxd!G{2aP`OdawI|z)?DHItkHzkn6H@~k-3B%K3c(U0@TXlj z92T^U)s_no%XJ_?no80JBkH2$A7}O-EelI~(tki9V4> z;UA|)-+b6Y7<}f~7h}UVvR2C%piT59K*dDZLfBk=vIFk+n1GMQ9FUDZu?~VZ-%Wr@ zGchcL&F>Wb!R+Xt2Tfvo0#uB~JRuU#yADG)cJxm``y-DLpkfg7g-D#Y>4fwA=CGol z3tDcB0?}8aZir7Q`qAMVSv&pDAfEFgK!t(XLKxBC={XS}k&k{gX!$h?L|=`%A%3&# zj)Q`hv)XbNvI(fLjzx3So1FqQAv!GCmZ`h`yFv!H&Kfb;bCZ zqTiPpeeN{G@fredDXdwD#7T<2QxqfmT8@XPgRtky~`Bw+bN+#u=Zk7i>#LSDEh$>TUpV6 z585ZV5@4m=JRzBb7GT!MW#YG!JbEEEG-6#+Iwt${#p>VApfG9eCx}0v-hDb|PhO{( zl*=|9aD&$rd?5CaoRkV;iPc7*DTGLJ>w(vux*By6GWyL$VJbfQ9`hFO#=7JTtT}rX ztG@dKYtCH3x@&1zu=OaGKL0*qV#+91brdF}&upXq+^i8xF;z3htQB+2 zZ4}x^@0F9%2wL4?Xt(Df0;~YTx2&4emjyAh|IyUQ5m@=AXw1;+ z5r2L0kyo+e(;qRT*G%T>sQ&ddCb{=C`!;r(qCYuc0p1=b8~t?9@Pi1jIEI7>7rE%b zv&{c!>5CtrFtwMGusI|2g@$fve=`5<+yy(av8>{z_T?R?ff&S!zDD;B#3Z^9U@;5{ zDLM9N9nS{y?{G6&8_Vd^vUFeQALUNdrLY!V|~bNULJGW8ibSoX$e;z~$~82)k320Fa3At|H2^$JakVbq`O7)rd)I!u)I6XJ%?oT>TulK3PgZXm;kV$I(dP#Wr!;xZ)uwe5lv0~WHPpGFKMKyi!_ zlH}SQ8*&Oznx?91aUUT({gl1@5t=jQZ+|JS0zpbcei2I3R9%B9Aw!fAz=p2DKn#f7 z#@f5Q1=^!d1So{@JN4X!yYPk~F*RuJG*(t)Q%x=2I7R!PX#oN3=&$ykPSHOk*OoH+ zdVylmH&%$yjj~riLAjv|YFa-U8c=SkzW)oaJ9M`ADe`v?y|8mAEBf5;5T6)s(c^dF z7^V7;bExFhrDU>?N-PBLM$wPiCnu(XR?L1W`btNgx$mg{{VXam!c$yo>}bmhVDJw` ze_X&KR`gRr%l9Y1Y?>=XI^$x;+_b6u`Zr0Cyh+!{FLFEMC42lE&`#$_fXNsZ z!fs0LqFuDP%SCfW*y9vzIV$XTtWW?u`YV0d(FYAbPl Q8&<)f(<%hC*N!lMF*e5 zB+p(}E`ZIq_PwxU=vvkz@^28!g%QvkOc26eG3ni=i3gF@zx*qn=nDH4>DawKEn9pb zC_efcW)7Gq?8;l205%EkW6?%7`hG`gQ5J|UO@JuLC5r1aVk>0aB`sV6ZzL3{AN zX1}AHD&@cS&H+Z!EQ-SGn2TsPT<=C}+qP}nwr!4WdnOp$wr9$074FnY&#lz^3ys?^ z{m;ui$s2T`yX&j}@tj*0+u6UaFAV6H7n%TwT`0o~ZP32j+WYgvU1=4F0Ll=}soMpj zPy|2}iUP3!MS&<3yFe6*03@C z_)ztzLbqXTV5oW@n5=i){kjy20%2!7Omcyjzvfdx!@OwGXjy#*VKm6d4d$cZ?`P)0$1q z&iErPfXTrCg76K}xrj)6jCPz2Q7BR%XmFFT*tH)0wKp}b-%6PsLCOZgl-U_1074oo z8;Mhi0F*sh3PlQp3k0x`zC|XmmN2g5q6uOFC_k4%X(bSJL!6xQ-UdfJl2o~Pbr99S zpw&%ZSkXST;h1Y^>qQTv`*ReE00?GL+#O+@z%&+9S|qFRcRrJ$_9{7i3WYxUonrqD zru2jv2#{jDAt?HDFY%S)BoMq~lLNX$c zII^MC`01Q2bRUWo2+lQjKm7^S&s&bVCe|WtjjK0N@Qv>gxpo+e00_1^(2Zn6QDS9w z1jvGTT;fG0_P?+x=@1kF5bV|_2T!axt<8p`WJCG-%HvXc@+`bD9DpJK!i6j&-*lnu z?yw0Y5GEVq1tANoeWJ8=&ME#V&Yu_2$`Hl|s z@>v#ggvp_k$%e2cv;F25ynANuLy-X4eCi#P4MfO>@VsU%M)#qJfS~I_IVGs0q2%I8 zf{=UX(i-kV5dy(9)RwS?&q`06fo*s9p-6!2dh`Q=Y|OTBqUcrV)4w{?Avp+8d*?tm)^AL#2YJ~mu$J< zK?=U}vv<6Jp#jgQP^3VxUSQ=Sal=%d=sn7;qd09r@wTm3JZ|{8wqEiGzOGQDK=49B zD7(Z}uessFTuSBrybxR!>G9K>Z+q|^d`+Q9f#8M2Cmd7><#2^+tiCHdNRGGw79h;x z@PCCO_VylmY0cYF8y>bq1Xh%)*=44Lh*kJSD`2n`%n~! zOHdSuMJNiy0VoQ@G8F#AI6&*VaMpF#ZUO zw)noZvUI1kA%NmHAPVKAj}9rc{Yo2vq_lNf>$%@WA01R^`*GU?1SGnKO*Vts00000 LNkvXXu0mjfZ?zsa literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/nr.png b/lib/src/assets/flags/nr.png new file mode 100644 index 0000000000000000000000000000000000000000..abaae2328566fb8d2ec6d3c594466a91fdc889da GIT binary patch literal 460 zcmV;-0WOJ*%m#D(%R_J+2{^8hDvFq zovzLZGJ|V`wch0J0W5$aMv#Y_!z)jf=j-z-PLwcHm+J2H&DG|NpT$mWrWikqNN1z| z{{Ba1qmiV@6FZ5}*yq#Q>5!wxvA)c3FGn^HAq0p}i0?V(!`B@36S< zvAEJ9Detqo@7mtdA}ZTYVDt6(^TWxyr7PgRA7^bxoUFy3t;Nr>CFqTg`~3abJ16w^ z_}Sm-*EuKQzaQdoe($ll&=@Y)Gbr6qCGgnZ7(902T_fRMBaNTC7dv*-A}Z4(DcngV z+)5>?x6SdP8}XtX^25owq%77nDD}?MIZsvg_xiEE(K=66&>1feGGpOvd*N<;+282h zPbHwQ#_-wR*gPj_ZbtRb)b;oI(6c0=u*mn;+V|Jn`ttPp^Yp2<%;Iu@=XfCe{Qc*8 zAkq=y?f?J*%}GQ-RCr$P)bY#C58r|J zRCJR(AwUX~uipS0h{%k>WMl+v;L6P9R~J1RJ3Y zA|0Vn2O^YUBYx&x;|PBx1Q)s6%(KeRPfH7lDTx^w9UmVZk>7^&c)yag^B9P1m0Aiu zZb7OhTZMtBX3DlK0&F}4D7O5`N0hfx@CHns?(R7&#AZ)-+7JWY#G)4fatXx)Qx8L% zz_h`zK|bK;m*FlYio#3IGYm>oL10v$@{h+)KMBv3fjgk$_HD z*Asx}U4fmhU(F9O4j%IK&|i ZIR+z$d*)d1Rigj^002ovPDHLkV1n_`vwr{p literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/nz.png b/lib/src/assets/flags/nz.png new file mode 100644 index 0000000000000000000000000000000000000000..c8263c3020ab72bb6ad099dfd30125676d75d081 GIT binary patch literal 1087 zcmV-F1i<@=P)qT~QMW$cV7;OnY_tG;%){kO<jTl>+x9sxIZOl zK;Ago+pjgXpVFH&|TUGhnv<CQ)Eo^v20GZ)}0-mtSscGsbce$M{lT&Ei95`2S?T} zIsOZMDKwyOtWw|qM%Z_Zl)`-4Q&9pY0xU8z%+ycDjaTfwvVN13;_&sQ!nE1`c&&71 zqF=7x_K)4=NB2ScOk`MOWHYw=z^&dbw>+jgdV}t%w^zBa95l|N$3%`rMmA%+y#?hu zZuCY#uxRD2?~~vBE*Y?Br6eS&m5-q%Az)b_zyd750xZCSOaleSa?5>cDhmJr002ovPDHLk FV1fdjDsun; literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/om.png b/lib/src/assets/flags/om.png new file mode 100644 index 0000000000000000000000000000000000000000..4945850be4e9686b5824c51caab356fa14a0cb4e GIT binary patch literal 639 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 qL_~lH5D@_)Ktu$H07(`3{p9}w?4Y2v1O(3$ zCeIco1qB5Y6BA@)WY|0-;a(u+bRFh(9q4}@A0HpLFW-{0TjVjs>ECJG7) z&>AJ0nwnc%Ti{zD`p6gey%^(YALC~qJY0|Wg0{1+D&UY`^^{o&KCj#0>;M1CMG5n6cpcAAP^7`f`Wq0&CTFl zAcTa3_xJbf>+6e)i{W7()F&k(A|m_G7RkxU=XxFI=jYHECh3D5-c}&lLLxpsKICj3 z^sN~k9UUGX9;m3O)6>)Ii5%;S9P5i5>x>)?4GraR9!>@h<#Ha+6eZ$gAAt)P?(XjI znH%q$8)9N&?2sGmksN-0e)YB(^|u)Ixfrstvc0{%_r4guzP`f3!uY`#_`(F5fR!$BHBbE+eRTHBO}~OB6M_g=zSgNejRyv zc|brwa&mG+L`3kO8Vd^x#}Fm(@bIk;Am(-+=64?E=H~5^9O7jk<7OZF`udTPk(QR0 z)iESXOH2Fv`{ZgK)-xm5HzVY2AI}vfqobqh);Qb%00XBDK%u8$yG`nnYm z;qvZQKm<%OIszx7BdBC_1Wrar;AC`!p6ro;Um=8?%qKAn%tcL>8Og#MAcUCAY-G&x z2ZYd)xgTNH@r4jtvUeFDgAPDw$-a@1x1n6LWFN{%X9%GsOXr5`55a~l+Zu2PKG|R2 z`hTAqq!GpWRwFu+@%j8Y9D+~Q!;dkxCRg0d8t36Zu?Rj{#*>U$o?v&(gdZ^oKA9=k zT@=fia^43Kd@`ql(X94*c2uMiSq>riWKLmB9t&$Wy&XZ?2ii~OaWAtwXR94RhL+h+ zR?Jjpi33Q*NxR7w)T$u?c*OIo-`}#gn69^fio~%tkg->BNWyoLJbRwEmCPw%OnykX z;c$LC=ddQg3P+4w6v0l179n#DKF*Etfi@RY)6Jtt{4QN5FYV zXKb#49QguV%uY>6U!Bh5qXLb8I~{sY9^%M(crk}JBEkH_i$_I8yn{w&}{2ZGSZ%Wi_;)&_CQy17oQXGV^kspCo!D})ipZ&`*|?tH?Egu2V>CZ;1G zYPW0{e`Dz?BT;M?0Z~2wCRfJlO&rN$eKajXw21R>-q>H}f{qsYwg}0?Boj5u>!d<#0&kBq3PRSWlu^gIWk31&c9aV9C|V14Iw5KMEKZhtZ!yaO6fAM?Ng}5 zjC%Ez0T=dFt8V<{wmnnk4pbs>7pDvF&0LGQWlp~S{mkmGL`jPm3dyH#D3N3?#jZo& zG61QvN^Tv=w~Tn|RgzJVSj_n+B7^gY$zUY5oH0CKuh??L?K(dTzi4| zl)*^pi`tH~rwm5OFBxkW>4LOTC2;>D2;q{W1hm_Z{(4EmI`m@x8loFJ^Kp#5Wl zNO!pz`Igad7n}@_(38OkIT?)5lOYj$G8mvI!yxoz{{in797yag@f-jE002ovPDHLk FV1kyVKD+<` literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ph.png b/lib/src/assets/flags/ph.png new file mode 100644 index 0000000000000000000000000000000000000000..6f73a4f3ae92c2b6c15f84632a38c284380e8007 GIT binary patch literal 1348 zcmV-K1-tr*P) zSdlIiq9_+u&;51nML_93cO{+Vu`u){k&gxWMAV<7<}fj^?xb_J*4HGXq*xdY%5~t; zhR6y~#)BqGkT!DIs*h=;g)ANmBfg<}7jdo(ext!}jAb&@-t}*P9gk^02 z@W6G?e4TDeSk}fE7Bh3_kMzy1NLWdNA&fy#pPL#ZGj78dzTso{Sm524J1wGSA4YuTX|zX(TVrl~#f>!|P;CP5 ze#EV*&_edZ-Ozl}bNk2QXiP^%pMjv-5Zk@sMj7`b8ZO1&56bl*p9)^RP=A54Ix3t? zPvs?g-mz<}(5IkS1%V5}e=6!ufNBf4H6jj0z_lJIR&YQNv;ySgQMm~XSNV}8oTzBB z`nXfp*4ONJfhWPHX{cC2oGKDofh6Tr7UYvqy_3eMsMQHjM+{#6!G_OCR3u2ednA?O z3*4GeWacdza2}{O zC%<@+5aLqX{P;c?`aFI-hDNXp_WjD({EF>j9f5$krjf-Fs5XGFWvpJH+<>YrW~}+# z*b%@ACN8yNaWV8oJQjq72d>!ivrx4kxhvR2B|8nTf^r?|&tjyEG9F^n(1o9d+N0J_ zLyD+7cg?Y46B}XT%bEqgyYK=}sP#cY8BbHY_0xB^*1c_u$qFoDM9p4QEGEv$ZXG6~ zde{H8b%+U4`i`CbBTq%!G7`takSCy634sgDo6?hUo6@4-T0d@6x(wvwP`SmlDHRJa zjB?Z7Uqx!#B$GIn_He>+2O0BPc8U8j?r06%I>kAHS5I!uqO6_@$8i0gQ}tH1%*2=2 zL0Y>XBfiD+nGe!OXlxj7P;In)kdBl&dvqCM`%HXUZqfLn;Y$1s+)OmLXm(Qw<8KPS z%RMI977eS>$)_**nXj_lNO5I-^Up6)^Y0@S4#u$Ry~kuF>+B1FVT7BZk%8+QS&XOgChQtdlo?vK2cBq^>E zF6{=>rQMTIf1baEiB@ji|EpLn$>_H=E7B#l4--2Fjkg~;)od;4h-@7q9bG-T4U=3% zuvneJf7Wu5riz4xEKwggDJxY^;t;_KdHUL=K_>~qn))BxxMA>g+05qv00000{{R3U6oMi0004NP)t-s|Ns9c zT|NK*{{cZ914AAHLLDn$LOg6xMRZxj)5}3|RWW5pxy!-&`}<9LU~7{{3Et zZw5smma(Fnw5AbFDhNg*xXQrn@$M8)Egn}kr@gTQLLO+2cn3uxi>a7jhj1fWI%0_@a=Gve-}|Of1ix#?(4J0yNRck(%skj`}!qZJpTUvEMYE#?%G=!s)z|hCh-PRCHDSVxYRe)zUXiGF_ zNobQdSQB-h_S`Gdz^_YU_pwgm+$l0j3`r&U`uS6SWhh@iWsG$`Z&QAri)oH|vBkOj{QJ+_)H`fYufw>Z zxvMp3N+er5m9U}p`1S=vAhO1~#nj8l*3R1F-t_nNl&_#fb6CpQ&=pWFGiFI4(td*g z0007XQchFU_#mOT4FCWE%1J~)RCodG*n_qlK@^4In|*R^+qP|Ete9iPqsPzcuCTE* zr^5PP;BS^HY~ABi0XxJ;MN~vZROHWz+?O4xtg5b*eJ3@wb+R8Al zNP7p+Nd{frtdaH}ptp|<`UeI%BOL&S$Y>ZNMASVx#u6C^Fkx}klbD*GnVn;~llm3_ z^JKOF0E<%zS<&t&lu(t-SZb@=Vc|s%qX||QIXp-fB2k9bN(|q`6J+E{#_E~Y zU0=1P()6QD_6;IzE6DFQ&UeJL{`PX~T?>%qTMPeWdG`H>(~qCT|I^O3s?WksuAOgx zGTs6!u?X)@s|RL1_1t^L{4RdBo0qZs4FwDMst^oS%G$>lOHH1jr>Rs_#~v!8A}aE4 eMm~=oGeH0jWpEe)+F?Ba0000o)K86~=2 li=*7OLPc9L1yv%s84^D8RPYqup9$2<;OXk;vd$@?2>_;=Gk5?1 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/pm.png b/lib/src/assets/flags/pm.png new file mode 100644 index 0000000000000000000000000000000000000000..6a196cb7e81ab28402ae0480a009aa982e627ec6 GIT binary patch literal 165 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 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/pr.png b/lib/src/assets/flags/pr.png new file mode 100644 index 0000000000000000000000000000000000000000..37f3b64714abeabe4f49b9b0ff8435820dc736c2 GIT binary patch literal 1211 zcmV;s1VsCZP)1^@s6YD=Kn000DnNkl9d`B1ED_o~5`E zAu%-&FG3jMtGq|w^!@Q#9f2B(2O$y(%iYDI#I^8Qp`-@mL5M`YBKvVPdUk3wUW71| z)xV)pj@h^uJ{~n54?-j&SALCQX}aO9DjYQ;4?-kTl(~jA@heb%;YEl<@q*iMCQ5p0 zP+o*E)YZPAb=HY^95x0uEDu5?VpM#Fi7DIQgHl5c%!3e#4E3L2ch4m-4;w~!fNVk} zs*N?_@jC$&!3)`iFv8Z>qTfmj^kxwh90-w!-&}`fM{E$t3m-xxa`!gi%snS4I1wVz zaHFpV+O6Z!eSGlspb7{EKLVJc3pCK zl3z&3^=D47C^^I^TYf1w!ic-C1QPNu6132{|9a=_waJ?F)iu7M>x9?%bm=afw{Hg= zUJ=r9ff-V~`zk_JL;lfN%!*GjDMhQ_E%Vdz`;nVJX5B*l4L%ztXDoRZ+v5}^Ari5h z>fjXcLrmRa_4)jza^6+A5-EA$3yIoLi*4uaFqlPH>~Jk{uw`_u={siIuR|X}g!}zE zvj~Ib`^Q=B!1E6RYL1sD@rSGW0o^kW#S2a3z<-2vUTB8hAtEGk>5-ES0Azo(#4CRv zbCcA^C#5Q|yR7t`^tk!l^JNV|0Q#@ANXg!3>LuVjuz8*SrOcL`d&c( zzH%n{f1kEom7r4KC-q9BjQ?EH*mu=|XbolUqUaG4be+lm4>{Cire0&b2~r%o;b6yme%M@UG0W^0 z_VBGB+gjG-6fJ2ji*e|>1A++jTVY`We)}=$I_dG?jo?~VN!8wa-Ik{2H*}jwtGz$W zLms^qP@tb7SRcy{F3i|vrTviLgeZD0Btc6(Vm8)!*3WmGHlFeO$wd;vCYd8QSYfvL-2@3~#KGxz62i~@ z5E8SggzQEqseu2fNuhnkCxbIij1aB->eTu@a~5|XIg z9V|{%lkx-)m96{nQQ4Y=)XcqvYQHn+*%1i$^M}k#)|iLW;v}SHwke;UhKY8Uk7t-6 Z{sV@doWNOA9b*6h002ovPDHLkV1hBqNksqv literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ps.png b/lib/src/assets/flags/ps.png new file mode 100644 index 0000000000000000000000000000000000000000..cac9ec76e3cdbc8225f57926e421c356edd02963 GIT binary patch literal 385 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 Bv%CNR literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/pw.png b/lib/src/assets/flags/pw.png new file mode 100644 index 0000000000000000000000000000000000000000..41b95b88fd9eb688a0aa790e9a18bd464adbad7c GIT binary patch literal 578 zcmV-I0=@l-P)h z6!O{+fxMMYuF{vndzr&|VY9o^(Kgr9Fi@}0U$VZr%Tv3{QNYbh%FsT`&^^r1Jk8KM z&Conbt=4F^vud@lSg^%UuFzhxzEiKuceV+6AipjaxzIpT3yDlXqbd@4&_NnVq^5&hBN3s4 zobo;i|2yITy71?O^ThN2yZHaY`1^$8W^_32c$R5}VeWFMCdesbf@GhC)dg`XGwy8S z{bT{z{NsJ{O)JW5T4z=P))H>gws~>EYqw)YR1T^Yiuf_1D+e_V)I*wY9jo zxQ2#?hlhu(tgO7eyzlSt`T6#o6xVl;>pFu#d~{u+}zyD%gc+4i+r|_41hkV z)VKEh_fxQP*6G}gjEwN`@WR5vuCA^SgFil>Wc>X6@$AgCdj;NbD` z@#yI2t*x!j&dv~rKW(&z{rvRt+dIqY)@izg!^6Y0w6wCavQVaT8H+~!{r&Up#Av&O zn9{DcwzkmF(BA9d4TC))lT7yf`1AVqfXbUjt8L@%=jP_-&f(T6oKZ}%a(ls)dc~F4 z>E5KIr1$st;q2w#>*Vb3?cd+usl4IxN@8e&CmmD)`ym3E_ zj5?loG1Axw91;DbKPj!$z{Tz!OXSve{@hOtvD}lK?;LmFm(!|CWSPlj+0K>yWxe-M zUqXmVaLpC-GycrN;!^(1d{Z+82NXiS;ScD#I$h=)`NS0=tz2iI%yCUkp(7z=mJMTh tmMDCL8?2-NR#PAmiSUq!L?j{+25%02ZgJh<{pbJy002ovPDHLkV1n1%gvkH^ literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/qa.png b/lib/src/assets/flags/qa.png new file mode 100644 index 0000000000000000000000000000000000000000..93f3eda7bb1a63834aa20777345def63fe94c420 GIT binary patch literal 244 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 C;yW(@ literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/rw.png b/lib/src/assets/flags/rw.png new file mode 100644 index 0000000000000000000000000000000000000000..c01b9a6595c510be6ce9bd1705c3f8be71990571 GIT binary patch literal 1058 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 OHG`+CpUXO@geCx0@B0Y= literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/sd.png b/lib/src/assets/flags/sd.png new file mode 100644 index 0000000000000000000000000000000000000000..117ad21f672492bb684f31606de90c9477e333bb GIT binary patch literal 374 zcmV-+0g3*JP)~_WjEvvDB;I8$P`~CzgZcLG+kdj+=|@s3eJ{lO&d(B(dBi zi8X&nEEwv?10H&Ol*aAv4zcu41Y)W5h?Tq6+B-cm7RF+W)mLmOi5ATM8*9DB>htXH z5o@;Giqb5^K~JBDUad9cSGRNI{m@hQ4qSsz U`+6Sqn*aa+07*qoM6N<$f|k*)8~^|S literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/se.png b/lib/src/assets/flags/se.png new file mode 100644 index 0000000000000000000000000000000000000000..b6fcc62855c6cea4a6f3ebbd7227fa654a46f0c1 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z`!VDyzv=#&dDbWC*5LbrGSeNCn=c%xh|eAjv*C{$te!3JzWZ){@1eIX}DO? zku7=EXjN*+=@nw)A$G#{5np8ObQj(@>b|unOHs3z_py!{Saw>VZps%OhO>3W|LxtQ R+<@jWc)I$ztaD0e0s!paJ&gbW literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/sg.png b/lib/src/assets/flags/sg.png new file mode 100644 index 0000000000000000000000000000000000000000..65a0422fd373bb0e90df785ce2d6c7dda632bf87 GIT binary patch literal 927 zcmV;Q17Q4#P)0{{R3U6oMi0004xP)t-s__w_O z|NreNIsgCv?J7F$DLL*oMeQp)@mgl`Vs7m$JMc_e^m>HwP+jgbLh)T`_LracrL6tx z?Ed)q??zMbM^*4qUiX}%?m0;EUu*vK_5b|+@my&2gN*JmK>z;!??6xUZ+iHvvGa9+ z_LQ9QS7hxjKKj7L{MOn2@$&YNng9Fy{paZSnxg*l^X@oD^nZ!+X>|F!!1=Sd?l(sF zouu@Ci0(B+?l3?4!N&7$dF?Gd_oAu){r&T8c>nzT@?~)HYIXkZ@BZ)b?lD33kC^X2 zP4s+*{`L0pR%89;=l}Zp@JUzw=;`*Bp72Un@mpv3r>*(D!tOdr^K*Ukb$|Zz^zJP^ z??F)YjFtDKs`sR;@l|5-V{h&(Jo&o6^m~Q=?eFe1L+va)_LQCOJ4x?6Oa0{L@?dNI z?Ct&S?)kaD^@fl5ueI<^TKdMy`pM1v&(rz1z5LzZ_^Gh-c7XJGgZ7h~__4S7vbg)x z*Y8A9{NCaHK~#8N?AFze<)6&AhpiA`rPjc&_5sEWQ_k zguqz-Y>x0||9$0@Vk0>)79G~o@+nd;Fl3~+0!U|b)3u2z!$$hRcr8P9!VXq{j>1T4 zc*saQAeW{``E?r(&r}=_QNf7qFeXRN_U-B|%huKI9(5H9X#nyGn#)Uk3)DiwLxj8< zz(PI(^4O?bzA|e@sg3Cj3waL62{ie*!<}v-iNXUr8d3rzYao;{t%+!Gu#hYuCBaYq z5g=dxE-G0?LPc}}d1fs~zg0Y_2>k+x+vtJJpO={>#s-J&W4ZAn9>U%N61@v`q>qqN z2QQN|#Oq>+h+GEcsnHK((P5*!sC45#^&9P=B%pqe_@98$n;Q4uz|!jYPtH)b$fG6 z0{{TR01SeE&sf;Ct2NLokR&7$i9{liNF)-;7Cd&Wj4`sGRkZ*B002ovPDHLkV1jyI B`ECFJ literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/sh.png b/lib/src/assets/flags/sh.png new file mode 100644 index 0000000000000000000000000000000000000000..f77da1f21a1e93440249643017b0f2865201791e GIT binary patch literal 545 zcmV++0^a?JP)}? zZKzgmssI1~&lD@$PG92Y@bkpV0w#V`Y^Yansnpu(GJTjy8$JB)7k0MCp^yDnq+fQKMVR7GLa^Y=!;ck54Z++r#eUG2Uke|kppvUKkl;??* z=#H7_kDBR`oavLE11Ep*w!QGTzS1Q+_t)F^*xdZ`^ZoPm{q*(y_4fYv`2P6#{`va; z`uo!+JW3PvTL1t7H%UZ6RCwC$*SBuPFbqav%9Pvf>Am;f^Zt*PtHBur8Yf(WAn=)g z;M)XB%38ZN)*9(AsA~L9Ra@!rdVNzL&+lTYtR+TZ0AWIPi2wr#6H8wxSKkA(5?)5pY7+1YO4rFqL__%`bS9og$86m2IP+*!vpC< zTBG7*s$KV|JE?=)j||Bdd$U)a9EaAZ=Q8iA%a~fddeJIJs(kf%@dUp$AQqv>kuVwq z<0azu&cf3DGDo5yse%pGs809~XRYLrohaNf$)3tFBBV4nGNDfa_r;j zsmS1KL2F2hzP{GzM~b~{L29YR+-^T<8*Z-a^7!iV_-{XGuFT?XKWb~7#{B*M_WAtO z8@(}l9sh_uv&vD1jN)NM?4B22N-1g*jY@p~Qxv#D+Lq2wR_gJ7H~Zn8n)a#M zN(2xAByQVGMl9SV+_T6h&f3YEfHmNY{))YRK%9@ui&zHAAjwVN8%Q z%r@}7bP0l+XkK&w+I; literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/sk.png b/lib/src/assets/flags/sk.png new file mode 100644 index 0000000000000000000000000000000000000000..5ed13487ca8f4c5bdb700d1e5164ee6f4d3c2ac2 GIT binary patch literal 1429 zcmV;G1#0?1^@s6YD=Kn000GCNklKE0S z*;RfCsSl*L$7DZ{-YO9g0zx7n1cXFD2ndOQ5D*dpAs{3ILLwjpghW6HNH!AFGa$so zzFNn|5fHU9)oujcFaN%BOAZGCQ6ppdP}Pg-+_(i|Mkd6xbY|Ue{;KDSx9<=TH8K<^ zp?Xnm6Q{u~{^Dhyc8CxcPe9a2ACyn^qMBQFfLo50YkdO3U%d`BA|U_dP`jw?_2!ms z)Og>3T)6ap0qHpFEMBI^th>Pi>wXXLz8e}egSkaJ=yMmA$Mm@h!7WR-K9I-#bHP-j zJ}f=@DFZom7F*Axu-|?k?Dw&DC0?dW_Syr8qH?~NJOge?Mk9p8WLCmHQ7*?PK)ieR zvAl9cF&=mH1V*g7#(w)f@XH5MuHSyZ=~Mgh#?HF*VIK78%X*3^)#MnY490fvi}KWe4L4h>}}R zJI%^guR!z$yoiidYj^@#v9**tY1Mc`q7E7|*T|12`rm5-!W}+_(QB>~ z5GDUue;ok8P@=-?0KyKm8c#SuK(cdOh7pz?eSHEFo~*<9=)1VzvZLyGhTKJ12_4va z3jxW_^LNLvDoM?vM*W!=rOJ(!=l&Ho54!`^?Ji5t{z%L+J?sAvkctBiK(gAP56B}g z-rZmQan!#Q&iq>p4}NjwmyF+ok+b47kNIC|mg4w-CFQx{f91yk|FTH^{fR>_Ryt4I z7*0T*ic93IkTJL_c}#+t9^W zn$y)B8q0-35+#JR-9|vvxWmk|>?31hU?KcnWzN&j8K5sU%M|9zP&~#y(=5l%z>0A0 z*^kYqRQDeQ@W{iVhHC3GRu zqf+GFgMj$xvFmT(PEsZUL+8A3tS>anadgcQRvv#*WA*z9q;=6Ac$IEjyce#W3`gww zX#5pA--kcvnLE}`---vfb?BuT%3{Bd_InNYZ`lV${_J_gU5G|dn9n?ZZH(|befX1M_tBszy=lFXI@2y4;?16=kWf)=s01{E!PC{xWt~$( F697#~Id=d6 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/sm.png b/lib/src/assets/flags/sm.png new file mode 100644 index 0000000000000000000000000000000000000000..7ce471523f0c391fa717feef721b69328fd93398 GIT binary patch literal 3623 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 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/sr.png b/lib/src/assets/flags/sr.png new file mode 100644 index 0000000000000000000000000000000000000000..9a054f012ded7269211a8efb6ae0303e96284bcc GIT binary patch literal 567 zcmV-70?7S|P)0{{R3U6oMi0002qP)t-sH-0}i zem|SOpa1{=!81^_3N5!3Ew>Xa$4w{4OefllBHD^0wi7Js!5-?s9<~xJ#z-gZ$Q{N< zDA|Q0wGb`ozaF&@EyY79#6v09fg`;qE67hMwGJ)OZ6)l-9l|>)=CvQfIw`psE8CAE z+m0f%3oXoBChNl;%UUMBEh^)yALFVYzbq=jH7db1DbjN!({m){u^#2HAHOjw=CdEc zIVr+9DZel((r+ZV7c99LEZU4B(QYKk^z7W1<86p%Hgft=bW7*k}nj|r(z*L z2c%W0jGoGsdGC{I4PDi%^WX7ip#ijNEE>wuwY1zaR#sVuu)Br0oh)Rng{;$%jTW-W zLd;eR*)}9(2LPJ8drbh?Cm{y_e1}fw(J_D%4q{Gmc5dEQ7iYLM6yyrmS6}NJTv3qQ zyZhE~|8Pq|9=pZ~5QjkeRIdmTu?h4mKYJ*mh$4ze^bFKgVOafS>LUOE002ovPDHLk FV1gMw?Uw)m literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ss.png b/lib/src/assets/flags/ss.png new file mode 100644 index 0000000000000000000000000000000000000000..583388325b00306bf2e468430d9b8589dd7b96a6 GIT binary patch literal 813 zcmV+|1JeA7P)5$2a*>|H81Veo?0hPODVL?IUnD z*f!a%ZL(daPe+of9B81izDu;2P(NTtkTNhqV|^EI*rvMmJg{J4eHVKtgx`Yi@A_0qqYJTZld)Zb<~TH zsR0&lf@#0nE`5R^0Sh-yr&2{Y3|QFNt}bB-aM#7hrnrv|Y-+5PQ$|Ba*=Sx~FbEaNK*sJ)>e|!s*4kcD-`Xj?=y)avfqP zEXKM{xIVmfpORz!Hou%=#m-7oqn3^R2FixD+hsl|uW)_E^tV#|qpp8tda>DVHCQY6 zhFzzxc&vS{vynwPYs+TuKDhaJkEu@{W4}J!P$KB|SkD!o3%hUo!7CVRuj^byVeaaZ z`8yA6`KPf;&V^p7SiiYiEd=Hketn4j6Q^Ma_Gt(gczxxcIvn$wbW5)so^XEQ&fSVl z9lB4rd^dHF)}+)vx%TUOCH|x|=R(Xq+YiIz4k90IDLwAMgY%h^5<7}<72R_j7;<#V)DGHhRaIa-+(1L&#@`7RGsFZj|5n&d}JY2ZHO2K zumt~Brqm8G0APvkqinW6Rj+{_K+0I6;{unMMAc~_{ui+L@N&A+1o4l6CHizTMNWwS z0xZ#WlFbOA8vgw91XvDBTwDfSs|!X5EIy=$t}q831eV~{&lI?U3ku75hE0t^&7J_u reuaz4rK|OU1A!$3Hqm8P0D;q2d^KI67o%f(00000NkvXXu0mjf!I_OU literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/st.png b/lib/src/assets/flags/st.png new file mode 100644 index 0000000000000000000000000000000000000000..133edbc09299fc477334d467c68430faba1cc354 GIT binary patch literal 487 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!3-qlzV7P*QgZ@)LR^7#QJnrI0h51c8BQ-@ z_tVrOiT=HtPJRygR_~?jXa@lMKI3G5kHlprg#7tIE(7zSE9@fsxJA z#WAEJ?(U84lUfW!TrOVc?fIU!_xruS|M$Q3bKKInYuU0F4*H5a4tlb9aFyJiuOP$m z(1C;9$wJ^zqX1t^fkF$jB9hRDPm6kgwig6$HE?Vex)Z9&C1|o}>gHk)`B)f4-rnuR z(wdPfVd%rsn2}l#JMF1X(zowBq*R=kCZ6(MFMPJ7YO;%mLX@W2>01?6KQ1MfFPT|c zpZ(>z5{HZKhL>VL#T*q*Nx1K^bN6w%khvG~J)0g{JI79?$zjXK zvXJ(}<$@}k3Tj>%|H#~$8Zxc7rQW;6XWPmXPhK?m^cA0Y($VX)&UV7d&?yIB{A1$U X+@Y#|(Qz>_#uz+Z{an^LB{Ts5^A5WT literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/sv.png b/lib/src/assets/flags/sv.png new file mode 100644 index 0000000000000000000000000000000000000000..acd4a36d2051358a78579fdb6b3828e5fe4a089f GIT binary patch literal 984 zcmV;}11J26P)VY(|NQU&{q_Isq5t>U|Ns4}v)K9i`v3m>|MS8B_R;_Eu>beh z_3qKp$Di%x$n)#T|Nj2}?yCRz-2eIG`}_KToqkVZqU`JE`}y&_xqsNaef|CY)YaBx zcc_1!fB*gc|M9y2^1c71**w&@b#7h6n0oTMs%*0s1#c!g)mfzgQ3@f9St&qmi z!TY|W!$EaFiKB*Zk7|*xjsEn@|Ni*@?y2qY=1+f2Ren-mbc<$xiA;Y9&;-&3F$vZM?(VL0$*n!~ z{no<&`V2tqpukTe5^;t^Bq9-s{7f#lGRqB9T=WRH?hBY(k@dZO+=dr z(K<3jTyIw(ulj3YO}paRk@!JvBu!{VDUO@`rib;g?#pB=R_L=p>eO;v&; z(x24KaYXjwy2%xWNL?b!JVRtOo&^k%yZBh_vsI1=x@V%F3{SB{5Q&V1-|gS?{2)6J z4i3%Ivr?Gh_L$+*4hFfQT1^@s6YD=Kn000UGNklXF56)qw#;s|5h4xxCb(kz)ng2SBT7ivZE7L9MQ+-0>%in!*Sm zdZ{EH-f;yTx>0i&0)(i(ydt@1aWHK#0^u#fh9jBc#+oW&j~- zP%4Wm)^1=%gi#=R$@msl2?g!CP%{|K(8?=VC~!yzi20a1+|8X6kj7GZg1^OuxT)Blfws8v-El}vy* z_XjAS{Q!P^dvLr4qtw4YN*?tMVP4Wicu1~O($yprved{6e8Q%9I=-dA^OxZ z#GYM(_=^jXaA`imcW)w(C0(75ER#vdu-S;>CqaMPe z-X=&=TcIYRGZL@PBOsoy9Lw?GhWA9pqpsj)`hl000F^|9*Qs72VU^8UL?i4&fbehK zMa`+Rkc5Omk(!1YkDlP)`4u(iTA|`ZClp=lhpON%;Ft^q=R_Y=A8U!)tG_{D`3veE zZ-pW=i@cZj*G}EQ{<;Vg)?B=r#BSY@!gwDb0!wS8_ZWzT0b`N>cGI-acY5VDd2Ko) zcE}`hyIvr`o1{!mi7D*aS4Dxm1Bfgl3W)>8V7!$%=HGjOy|>)4$1Dba*`;BJTRwJL zCF0cnTR3sn1%}Qn7`U;q%Q686uK8o%k^A_=F$YI)gn-k32;QXzu{ft>#+(WY16b{zYkkIi!f*VL9}Sm0$+UjCAM0{VyjniV?79miEkvi zZG6ZSo#q4KuAqm zxJn0!K={WZ4343VfNVA&L-oO<_z=nB;$sTC_f=CMuTklYxiC6xjwQ|!`1;yZEN}{I z>;-ly*kWJ^0|NuBSg``T&fdUg_X4cF=8n5|?g)7r3xm_Q;XZ3E_;(-RLsc&nW|d5t zRY`%oq>42gVfOn40%4;^9=3QC;*d=^Ts*wNVzE$KT1qN8IT?2yykKA*qkFBs9*HfU=5Du5zNI=VPSA~c7~gq8`x|%?CtFdthMKD36P-at5AFS8lIO%qxo*@*$ilO>U9io)fDG7su9#rwzJu6(;4n^~J5L65UGLbpZy$kj_R?kS zJA54Ht{7v(rN$m|_JRirdkuh2g3_gALsDEa3LmPt^m5*}!>(0+*7qX*%k=_~vhQAmtg$ksR6`{L%-|sm}N&lKPI&1NnXT!M6el4Gkr| z;US;6~mxKRaZXtM>9y9dz$y-}XN z2mo}`Rbu9i1NU*lIuKUw0ffjBy%~(!glrLHiokW$^ND1qP z+=woaiYxK5L=vTD%o^KleFK|25VcB-{Fq+wau|lH>;=%M6;Ks&P`+Z#OIz(7k=APn zeCKV(sjI#)I%1CSiHnfjXE^fP>d*O-DKq!ae^D=yXaN_YB(X1oTn8aHZX;e+a&{%} z`w>RvjSZtf^eTUL8DX9SkQ&wveAWUeq?OP~Q&kP=!$%O9S)%&TF|xMMZmaA611Xs@ z6IFW-kbNt$k00bo$*32Jp_8~S1)TWdhzslqPFzPwYGYrBsEcMXx!PHj;x!GVK5JN;%lKc3rAp1XwYFIl#9M$gMwb-jS^wgRPd@~^4MdcGAKi4A6gPc3_+{1**5*Je zsnsne$(ltjt%gjP4sqpORHyetd14#H2KIuV^AIvocbtR_yqe3a!T;2~Ojmjv5 zcLUK&R1*U(YbWxf`$3f12t=4cu1T?@+M^)48@S1B!B781|2RMGdsL;gM38HLlq8LU zu;eUcVzxe_u2{t7XlGG!3g82Q=)nle;APqo-X`Bbkp8{icn8bTqz9PZ8~=PSBCn~8 z{~jf&i}Ac9GL>fH2D?mZ{HFoYk1dkgrw~`%g1Gn(h}cWO&z+2_j6o<*9geE3=@7A( zLsYa2q6$-p>oV}X(pWs+k0Xsssp+2#dm zSH;yvR53M~0YGlrC1q=8QBrDf69bXS)#|BR9Mh<=3;>dqU(Nk#v~dwNl>tC*J0xW_ zeMC_pB%-EoaZIH~G5|jbi|i zXPjE@&tt9^P}3Ly#KbivLmN?IYFHBkQ7AR)IR-9C)F=i3$t$Ym{yOG*J~fE}K+N3J zbP*+@1~oAdrAnioYv`ItjbQ)~c5z+huVZfHQBxQI#L6=x{fmB=gwzlQ06Bd9Nr-l1 hP0{{R3U6oMi00027P)t-s0002c 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 P00000NkvXXu0mjf$DMvk literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/tc.png b/lib/src/assets/flags/tc.png new file mode 100644 index 0000000000000000000000000000000000000000..698a4cd08729a6329bee05b559320c7c55bddbbe GIT binary patch literal 1388 zcmV-y1(W)TP)FjS#XM6ILo!(VXdvm^n zho8;cG%KraGU)IghKc;~};>d+;t0f0m?!WzMrfuKhnQQ7p^F`wyMVLL+0wLSs5`Hq&C!eig-%|3M>T#!@RLIu;rkGnQI0(Xr6T zn6cD~iH?Ovb~*Uo)3C0D-cu_kc>-ec84{jUR9x9c^z{$i%kPRz=n9X6bC$MsC{Fun zSVM)ST@mq**GoyNxS|a<%e-F|#TrGMn6duyq@q}GdMX&T#llz^3u9p{qq%$1Z$%fxgOMe1qAf6*lAD@L)U`6Gy{G;<20v)1~s&Q^@zkB{uv2aLZ(kr zFtvqF8cJptdl^)n(`lAybwzPu76ps>Matk1p*U^mUP4D4IG{sc`}OwDlIrt;cb
  • `LEr@Rm?Ac(6ERwYuSaBLw;`3<3|bMX1P>PG`Ie$)`MNfx3-yH z|HY*6uu<`G!zO<|Rl64j3xP>KSYaL;$_GqnWC&Pf8dn>|6chB)CR^*JPswS$EaGK19>!oT*5S@b(LBgvfZ5G_~;tH6rNVWBZ0VJShT z)H(2{ZkIKB%UvKufa{>orz3t_q-m_&*G*eKF{3hA-C_LPLk6i|SU^EfIDZVQ(T6u> zyK-1)Oh{NtkSTj54%b~)U{M(yGG&Y->^+?V{?t#n=1qt6y2ALWUs@)8W?6q(yDLl! zT8HW`DSgSKF(F_nLH5j>%AQ8?{iw%#q5Ie974oOP!!^6}iIFsg-4@8NyP^YMx4uXo zv=-fqMtM`J1`z~jQCVEN6q(7|`l@5d5>N3w_XD3hKjfIff?`-jL$O}?!k@}rLl=pT z*K-iMnF~COM4l|sl!OFbdaEpV?em}eYbX{BiAQRE=p0)@>}Ls`r;1&tiCtL2DbIx1 z(OaPyR?$!_$Z1g;b=^X4F_6L57ke%fJ35QpJSDF1&4StC47R)#%6tW>u!`nlIjuf2 zQsX7(NKVk5CUKc1b};-iA&tg@e7Yl2mbVEwyrPX~iN>x$ zwqVLE|8cBSF~-mY1s`vVfMQL@;&^Tii_M|#&Q46wwG?_diriR&DQ*%skTMi|!q<(u zI|mBb9$PWicyB%-HJiG>s4|szG|J?=FpF=)EsjN*RHgD@VSGw96pR;REC>u@j$cfZ zReVN&{J|_Nq>XPd7A?X$LpF3Oe%rwQyjJ)a zj{$>P%Brb~|4uW!?iK)YIhIs!2dZQ(3Gxg6_v^=-DyuMl9HBiJgaLWBf8eNliifrvwU&^}c*fpR622WQ% Jmvv4FO#qSpH7)=E literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/tf.png b/lib/src/assets/flags/tf.png new file mode 100644 index 0000000000000000000000000000000000000000..5189a18f4a80e9e1a1ce86f7d07725eef1bc4e1b GIT binary patch literal 997 zcmV0{{R3U6oMi0004=P)t-s03(%{ zrqtTs@SUpG->bbOLZs?PR{#J103($YG@St?l@BnRB0!@MF`NS?mINl3AU~o#Sgt-; zuRvO`lcLg;qtmRn+^)IZxx?bX$>qt=>D1co*xm2#@A&@y{|+yk2Pv3rfWmNu#8hjz z3oM%V`20?0wOMewf|JXRp3r}h%65sy1t*sgGMuWm+^e_TDMqHa!r_^x)fF|K7B-$i zTd?No_2}#MA3mZ9E1CKF{ZD7MQ){@Uvf8J!+NrhMLR_#zU9m)7u|;39x542pN~kVN zsM+4{+u-m#SFVJW%!ilFiJ8udn$96VqmZA`k)Y9%q0%TuraxJ)m!;GOD3=>Lprf$a zrLo%F;qcw!@heEDB}1g^?)N7}rSI|h@J(8rs@7U@y1&TeFife!%H}amsm|5w(AMkG z*X+~T?Nw~J)!Xh?ZMj!&xiU_wHBqZ#c)s4_@!#X};pOw==ksQJzcx~ZbOiYN(hBoQC$Jb0xJd`lVMjzmQckEYxMfP*BzSiCP0)@*>uboq*4E0HbC~`@ zHZOAc_>79itaw#EKKtwN@p7?hA$Ja|u7Ke0WZ(wu{)tq#!gmk;AYTJt?$(eUz}y*e zB>0Zx1Fl9KWb4Y+4-$hVU{QI7oHFfbgU%T@rIFry zb_{G|mz%Q4L}HSBA{JI^;dH=FStR@scpSImpqt`1xd@Z>DUF!d-VgQEr8pAUqRf~R z3vP-c`bMsM{#1V<1=-{QZ;?n3uu*x7s31I2UL()ij7-#PB%qX8`A^;%mtsEv#u2M? TlrOP>00000NkvXXu0mjfiZ%`0 literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/tg.png b/lib/src/assets/flags/tg.png new file mode 100644 index 0000000000000000000000000000000000000000..028167aa0a2f2529362d3e53d497a718733fd914 GIT binary patch literal 628 zcmV-)0*n2LP)M2h50003FP)t-sz85wU zV@v>QPSOxG5n@aLYEIG-HR+3-(-%7Y@bcCqMc`R-|Nj5vafa`%y8r+G^vBTC6*&F$ z_5c0-)gVIOQ*GmDe~^?Vil8L!qOkF{!TY`h|IPr@6E^$o@BaAt)EqwBL0&^{{8;>;pW~=Xww!s?xnNwv%b_CJ>OJr{OFnD=Uh0pa?Vzvu;pO<*-r!kr_R-kdJX!6buhbbl>y)J3O=!@r z5zxF2>y@Sb_4namc>MA6@2a=^>+bm5;nyuq_R!b;^Yz<5T<@v2(h@f9oU7hbZPFAt z(47>}x(|n$M-Tu200VSVPE-Bp=9r`!^Z)<>5=lfsRCodH)CEEVK@ddICGJJsU2q5< z+}$1Se-PXqW^0i2zrY)9<5RU*lrpTJ$!1qdkUxPqbRbR*h|BHaBVM1Mj|9+4M}i@Q zBWxrJAZC45JfYMJBncp8eO5Z7)N>@81CTFpkYXuZu7s<#Fs=&MYHjW1a7U-Ph_$O5 z&+F+m|G4_FcqhVKk#gZ8={W4I|4w9=4q+!f^^6S!-VhB&4G zOwY^$sApNo9Dw-+t7{R!lJ!x`D@r{Gaj@{h#*acBs65$H6(~2f;1Ik(a;57R#}v06&17q O0000o_4`1RjQKv~9;Aiv-%2P4j{26D_jT^vIyZY3uwNN(Vmw5~NV9ZH<)T!RI5*)l84CSs5|0=dsx{eoGh@v3fJQKQy85}Sb4q9e0Pu@5 A)&Kwi literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/tj.png b/lib/src/assets/flags/tj.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb3339713ae979884122b30f925d19001a03555 GIT binary patch literal 679 zcmV;Y0$BZtP)?h7QrG|)sG&LLX=_ug&!}sd4>J=eSZfm#Uanu z#jvOeENUW*e<~n?<$R(}mR^@-H(;E#G~XEzjI*l8ku19jL$GYsnCj9|jcM+Ns*8eP zoYOS_G@W2MX_j{qg6TN&@=igzry-&y{3q%9!4kCyB_x+Dztc9L6ql7xAec6fa2ZcT z-f2`fy&{XJt#T?+YTNzv4YKkD#M3u+SlxKq8tu|h)kR~TQf5|bR8>~wSoA)0Ko~4r zJu$N}e_^E10#*p0w0Wh-Jqp2KNkeIn8C{lMgF1g(0gf8L>TpKy7}nK}-`2;vZ(+26 z)p|znu=cNkIz#QhRhqzRHKRKlLNz3LAgf+m5yPyAp)lTIL!zyC%gzAlR^Vlm;hEc6 z^kf#dfW<8|-*-bRL?)W=x;i`aS@a~Hxy}DAt$d>uEM>9isVr%!^<$6~F+!O+BIh7W zSd0lvH6*M0cv<<3B`gv-2UKIW6*1iUF_0xLVbN2N#9IE`sgFa*h@x}K%mW3Uwewft zh-xcxr1gD((=HWYv8eIN%oaswdB#@1uIoH!@p6QfD7hf3ULpZS{%M|f62@6x7TJ3h zE2aOl5IPLOg?uzW^fll2w7&L3#s#1V^`=9De2`(HGu?xNs~s*UKFg?h7QrG|q@TMiN}9OB@?HP{ N002ovPDHLkV1h^+HOT+~ literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/tk.png b/lib/src/assets/flags/tk.png new file mode 100644 index 0000000000000000000000000000000000000000..a960307b2594fd62f427ff9f1c53751c1978feb1 GIT binary patch literal 1503 zcmV<51t9u~P)PW120x(rmF3z&9D2XZXB4eau}T%odwl(nZ3}zNG;ece z^RQ|a3xjIYs=Dii87HsKIezg~wcv;xMMHLK!v-}=ygF;n5a?xmE`79U8zz^ z5bN7t-!>!m(vSodqeT9&Wuxzn>+n(7gEH;8+W=&N<}^wT^x_}7<8N0i76{VB#Ia|d*93}ItXgG!*H66JxvnFm#+{E9LL>E5 zx&@!xNRJQ(IO`s7er?@q)AKb; zcu1R%PQ_GLEJDb-ncY`R>3Vj{@cFhK7)JK~)uFc2yS2MFn_NfFf{bwS%ZK0cEwkD; ztMK5ZBV-+p<7TeCGjT}6m{`fe&G$j36v!R5X58%w9X~*(2@cnnuV+}XqUaPcB}WLVz~Zt?xw#%)DycFD1CShIV&!2sf$kiv`0T zVh;v##>(?8XCCRKu`T%e<-PV;Uujs;Q#NO-;H{Zs@aRW4VDNhN9#l$((raKC)+_IQ z#Nj-4^gz~>x3F{Z&8H!r#S(sMzvr)3?U9F4$dDG_H6#qn774~GZ{^rKx-19sVPxCS znjqH5HeWuj+u5#`v%H6xYn1j=W3deN;&xkI!9t2Q8s*K1Heb|LEF8~#x_rNJr}v;J z#)o}TB9qBGKE7-I=@#Zv2+NxeDqzM@1&upVCD>dY@{En9%A9& z_Wt5S(+4~QB~iRUn05CzY9JO)cD`S`3#ZXRsZ1aERMBf4D8&osZd$iAWCRwgtH<5G zH0uN%0#+_~539!BQG!_G2Q@Gm+9<-g;=~%+x9;on7IUoH zjU7<$-9=0L@hu=Va1bDA&;i?d#;4>EQY}@@#hT_ zZx+fE32KG)uAbX(Hd35eSmkXqzlM$t>dC|{eGlBPC-+9F4&ks_fF+drDuwK`xwO&v zhQ6*uj-G`J?9NO(-J+TsXau-AaPjFjH{MtF4>gp%SlHJqk~f?XAixvCvxFl|d_wr9 z36^f+8>Dj4UTj7H2%+|z$V_a{GtzscPL*^O5OP_T6PXG3fcp~@;#}d<9)WoRLJe_A z*9XVqhac9Jfmk?r(5=BgiG<pxtpR)-8h~G3E(8F1VekVqOU_f&T#P6rMsU1sm6N8i*;3i>3W<)R+PAJ+> z=&?zsqThr_+fXwm@mR4jJr)-XV6Fa_{{h6c*jo$E-Io9W002ovPDHLk FV1kH-@#X*k literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/tl.png b/lib/src/assets/flags/tl.png new file mode 100644 index 0000000000000000000000000000000000000000..ba9341704de2b80dc79b23e646f4358382322368 GIT binary patch literal 667 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 px2$nhkn-aSZV|p1h-*^-jV8 z?iZ_{PTRPVvok8s$iSdCMA!V%r65TOiOZKRofBI9)N0P|a+NGa0{{R3U6oMi0004WP)t-s;|dr5 z|Nr9(7v?1}r7VdVQTGSYwvV>^OBhKpr!SssrIa~_OZ42#K`0pBKzOrg(!AQtC-k>Pb`O94PBeSL;q#>rz|mQ(Wv zU})`NY2*_iF7E{{qFDn^Yi}n_5Swv{`mRoMo<6y`~Up>|NZ^xJ4NY2Oy?^$`NzuVEjZ;D zB=Llc;rzct00001bW%=J)WKNJs{jB2sYygZRCr$P*JW?>Fcbyg*`YEs^N^XDnVFdx zUikB?6t`Q~q#qJH+9aPp@F>c)eQud1fg0pzBNU+sMJPfM&S+;jk_g)tJWB!q?vMSA zF*3-~+!OfBU5dqz#D*V0VQwl+n318~JaFRcbUCWr<@I+z<+Tk!2vJU*6~iVkV$c#Ey^_8Nt$*ei4mBgJR?jAudTGGR}isnjx_-5h}uk zUqb$$5T33-Xu8OrlYj0|hSB20zpK5wHcQ@Jg%d=)OgAdFg8e(SgNQCdrkOTy=Atb z)eo|S_LJ5{aX&elY%mbrv}$d7jxMGYDIJPXgd!BtA|IJcVIP*CZfXDk002ovPDHLk FV1jKc%U=Kh literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/tt.png b/lib/src/assets/flags/tt.png new file mode 100644 index 0000000000000000000000000000000000000000..9b4575fbd7e22da36cec1246d0f2c76b3765ae88 GIT binary patch literal 1891 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 N002ovPDHLkV1fW8-wXf% literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/tw.png b/lib/src/assets/flags/tw.png new file mode 100644 index 0000000000000000000000000000000000000000..ec71c10bdb7a8fd79db2a8d07e3e7dcfcff7529e GIT binary patch literal 853 zcmV-b1FHOqP)0{{R3U6oMi0004NP)t-s{r~_a z0Dyl0O8@`=6&0QU0F@LJo!Hp#^Yi-m_x#e*?6tMv`uhDvMY1C!q$nt+DJiBZDyA?n zsWCCCI5@05J+4DTu>=H{MnCn*Y(b4Sa==Bm3oc8wn0s@u;1D5;y{uUOVFE6PY8lWE^qJe?SIXSI_ zgv=`|r^LkOJUp)D<@CY9PNwZ2y zw8qBg$H(YSPPNR;>Q7I#PfxZU9-&!Ty4l(9T3WgX2bdutqu}833k#Y-L9mpR(?UY9 zb92RXbj3P4t#We2X=%V}YQdP8)R~#p9UY+^9ilESs6<4uZf?W*`TYR_mHYesadE_} ztK6)t+FM@J?Pje2 z0007XQchFU_#mOT4FCWEmq|oHRCr$O)$F z;`HMB%TxrBo(U@g?A$%UM;=ag0YpT6CRiEQpTk#_*$ENR7(8pOz)vbR#E?fkrh*#U zqAr*`WRU@v!~@@GM;dRyORfQuCmC`0Yp42lM6ay*9V5hNqPr1VM&eLM<;L4C_FKrF zOGN|e?Th7_-$pYR6RgA$Y{36*1NUighV2*#HqyvYU^AO!eEHHcz;Y??W6q8?0w%&p zN-j0mghyl%#~P zNbc)ns00000NkvXXu0mjf=A4&i literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/tz.png b/lib/src/assets/flags/tz.png new file mode 100644 index 0000000000000000000000000000000000000000..0c67a2a06b25dba86f98e7e5c889e67637087a9b GIT binary patch literal 543 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MZ!3-p0rv|(LQWFAvLR=Y^+?Cs6m9TYE<$mqg z=TzRG7Z(v=@^xSja$yhMG&5||til623)}dXb@8n{6tU`1`0kU6&(EqcEWZ2aq8QK& z(;a4le2n7DPls=wnZIARV85>1R;&3fd<$CnOtzZ|@iQ&&=J&B@XJ%qpeJE__NyS|! z6+{J@9_VEgtl2-(4tnP%z}r|NX(0D>HoBll|U4pBoZ( z^Th3h-9PVr-tu>6xSJy<1KkwdQdEgmR(c~C+&l8RwX^BRU z8H%n6KDX|5oKQ$Iym2}9qU8GSWiNWx2VazQu{l<+JpHt(ECQ3Z!a5E`VFzB!VYdNF9lx#lP(Io{a?U%Sl_NAK`nmI);3^9!Nuuone wrq1+O!mWzMZL5;C!6l{5`z51itLD%5S!TR`{klJwfuYLa>FVdQ&MBb@0Qtn-YXATM literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ua.png b/lib/src/assets/flags/ua.png new file mode 100644 index 0000000000000000000000000000000000000000..42b2cde9a87adf06870ef4a9c513c5d580966293 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MZ!VDy5r0#tQr1%4TLR=Z5cilQH%@Do2en#B? zs|=fu@o563m`Z~Dg0K8gSh$@R$TReGaSZV|{`Rz?AcF!A%ZBX@tU6bi{+TK+{9e6D u{pH1^@s6YD=Kn000C1NklyDo7H+Z(~+v>y5sP zbMBlde-lAAjO z$p6Z1Fi0zzv1t>k6BZVR$G2_6_zN$@j5#y#$tRznJ~B3LWRTV{x^G|jii=SjKfd)A zW(*&K<;$1DIJ8Bea!|irs)~s3BylXSGD>UqSa2K9` z`FX@A#zTHrAF(4xGDvex(lpeD)9J*F88cwI+=L4+z7RVf+=-vUe!?5?yn$z4cm_ZG z@LipIOp@8G?;vXw1$s45<`s2dwOY%U&P<;@9YN0pAuT-(-#Q$4ZTWIIZoV0LF)^r4 z;BB`-x6fJc>#{UWLtV(IYRi@_Fc=J&zi2*2j~$KWEAKnJ&gG{F1szmG|iC!tHXE|542X3xOK!-tk10wSx;VMdM|$soGB8wY1e2?V)~K7INyNNc#M+Ihg? zaA5Q1&9K|;5K>c9amy{YlwUr{&dh}U@L`msq~L!xZrsS#@2#aA_iZ*C>Ou}%cieGD zmAQw{=fnS;J$qJegF#wTRaIfJSWubL(ozHk1wrN{)22;BU|=BR+)|mRo_b3Dm+ud0 zE0-->2D$VuWMpJu-@bjg_S$Rl=9_Oq4rMtxIpvq<d{$L~aBr1MN_l&G zor8j-h=-<#h^M%?%1KCgQ&N9nVT#_NsELWEUS5c@A~a4-dthIQT3Lka>+tQ%&sbN3 zQBZxhwa9C0k;TQ-$6#&Gb$~uSZ&+7?<+Zy(Kyh?)n0$PmZ*G*}-{`x$%*4dghGKw1 zL346(mP|`}VquE$@%8ld_mq>b#>LdSy3F9<=*Gs?=jQF_=k1l1vB$^N@bL6QLUY%P zl$VyWn3uAmp}L}?x}&4Jq@=s6s=%zP!BSCvw6w>yw8-`K_=19>vslhN00002bW%=J z(DtKsUk(5O0i#JoK~#8N?Uluj;;w%7T0Fnf5K76+@;Lwk91;o#yWe(Iu>cCunMie+>gxcl? zDI6R?%Eo4mclUf}jR3Xnu7X}}*MPnKUwe56#|E-UQ$7KFmH;>rImtWw?HbcbTOP8UO$Q literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/us.png b/lib/src/assets/flags/us.png new file mode 100644 index 0000000000000000000000000000000000000000..4e47eaaf0c21b900d12ebb3e9a15d7c5352e4cda GIT binary patch literal 756 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 O0000q&CY5s-Ltn=gQ zwp-8LYt*>IYTiDh{@rF1_L#jsCtb7MrgpoHbXlJ^&=%&BAiv;$Kdwl8e_q4Dz-a2} z;uuoF`1U4i)nNk>mWNH(a@s9-{x|e~HD%|mMRA4}_vMXbZLN>LpEvpWvlm}>a=w?d zHUDonN!b#HTr0naL`Eou)_xDUY^CISonO&lab1jr($tXqjUKtDI0QIPsk$^xQe$$N zRj_K>0+k-0^hqZBm+|aXDRq5x!l{YLWz{9u1_wqaRbLhk5ru$BE?`bzil*CYfv}`4 z|8j+X7c;S*FmPZ@s+fO8`0#HQt_lBMi3^-h57%|fjGceTx&EbLE!Sq7mC7eJ*d(5m zV4bdXdeX$yn#HSE#-9EWFhx*EbJ^CZ0*V1m>OzVEF%x@_CInY Pcrtjp`njxgN@xNArh3HB literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/ve.png b/lib/src/assets/flags/ve.png new file mode 100644 index 0000000000000000000000000000000000000000..cc80484c199fc087e36a9b5992f3d1c49267423d GIT binary patch literal 814 zcmV+}1JV46P)0{{R3U6oMi0004oP)t-s&lD@# zu@e9!eE}tY0w#V1D1ZeifCnmp2r7XHD}oCxgAy}_6EubtHHR8HiyAwM8$62~Jc}GW zj2%9V9zBd6K8zkdjUYdbB}0%UM35##kS0ZtElZRyOqDQAl`u|~GEkN?P?t7Rm^V|H zH&mH8RGBzbnm<{cKU$qYTAoB+pG01uL|>mvWTQ)Eqf2F^OlG7_W~5JNrB7(3P##@S zXr@qUrBG?6S#YXaa;sc(tX*`iWM)igezIwQvvGyDa)!5Zhq!cyxO$DddXBt-lfQzL zz=@f|iJHTTo5YNq#EzcDkDtbvrpuY9%bKXno2bm3s?D9N&7P~yo~+HDtj?;o)T+1C zu)Ef^zuC3G+P1*jx53-J$KK1+U>ek!p*WBvY z-Rs`t?%(9@<>>O|>GJCB_3Q2R>+bdM^7rua_wn=g@$>ib^Z4@f`1JMq^!EAn_xkqs z`uY0%`}_R+`~Cg>{r&y^|I7gY|NlypQu6=+00MMUPE*wW$-)vi00041Nkl#6o%pTTNJxuFJLbyHf-2?FW40eqS!n3f{N##JCQ46V9{CT!pxi5oXqSdPqL%L z2uS%5kVGUR5s64dA`SHv^4oO|z~@=IiY=8(Z`4dZ5X@u*o(vcW+sGB859dgKX9T>es4e zn;{}kfsRO?-FLcf!M7|MXIJ)o-H=N5EN9?H*-OEf{79*@+rvg8eiS_1?wTv%MsP?k z4unc|Jkt@lk(38|bea$%)9e%7CvzjVs;NbUX=Sp)#*45F)d-VS<-hnAL{J+aQhpo> za#F^Dq4wbfy4tz+6en3K?4zx s(kdWjS3nYxh(shJ5s66TpCTgq1P>~m(l%;baR2}S07*qoM6N<$f;NhoQ2+n{ literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/vg.png b/lib/src/assets/flags/vg.png new file mode 100644 index 0000000000000000000000000000000000000000..9cd84e239aad6c5c325499d087a2926ecf0aa25d GIT binary patch literal 2425 zcmV-<35NEGP)m>&hS4*cKHU7HLyc@~{|TUPJKfFI$P z@TZU2gW`gygse-SH+ObB1>R9Kgqy?j>Em35KTX8AqdXm+A__7TSg4tPJckL2)!W+D z;}(p93>6l7Cb;wuemOz0^Eh|2Sa;J{w|!AAd!wB9L_2S1+R~G&xd>~Mbtchm4WN)_t;Q)iYLnbG0G0G( zsF<;}cWBMOd4yvk0!Mfd!F4!VnzQ=Xk5hT5H2V zIQBW2)C6pbUe622)#qgUGkTmp)LW4E_K+4eYS3h1hY+k~K zIOKp0`W_F)+m_EVN^g#Zm05agVCc)=*;dJ@+a>7p=C1Jve^6m*xvUT*>-g$njl49b zd#e8^B|_6LJze?o)eE?6iLisI8mNm^bJ1Gtjpw700OdVaBw8%=Oh{*C{JtU5Vfwqt zw%TNAIxpuVlLEF%ddJ8F#bG>IG6oKKh~=La*wNAP_U+sLzP_v@p}?Hzv02I~LN+2v z+La}{)Kv*J)*oZ~_)&+yn+#%UI4_4Z^440#X+rEY5qaw9&6S>)@bu}^o}QjN5AMA_ zQKV`=SIkN$EnciLLkMTBj-;U{YAp0jACL8SlR+$Xr)9hp;wobmg0s5jhoW7^W)>$e zvAetb@#Du&pFQOiCK-FIHD0O;%YJRgpPCLHk@+YNhn5K~*56IG)iz7baj5{A;HQtB z>yDf2i8pk`PqWpm$&Ct*cYXHk*~^zNJG;9oj)krCS{JB`ndPZA+Y7Jbtf6YBi5d$% z6M8K4WGJyr1ZYIdK-mXnJh#jEOnqg^^qt!ScB~1f!2)Y=aIod!z0wS(pe4!DSN3iN z@7;1fn*c0qYC$Y_R9NVl&|{$|`}hmkW|xh3Fagw&+HJnG>U29CuQ~B7I~LY`^n!#p zZ{GCx_qUv@GjtkRM|P*?N^j+D{)&Jynucx>c_^^ZGoi;qOSXlA3Jd38jFdqT$VV5W z?4WHKV8TZwvGS6hJbBXF+xz%TB_CNASP(*pSWOqrc^-HnOClhn$AXXlbZocJR<&O| zibWy0uaPzlQ4EU1Qt5IhE>ymL{rc_OH_cZ#)BU%=Uv2kdB9o*Gv&4g=q?frWLoC;D zF2ho>U(EYHtuQtOjE#0yis4QE>7)cP39>el zhAv@jZo;z5Qnp*P!dzwX+G)n#I5`JxKqkU`6r}3IhC3|X`}+ExKYyN5lMTPLm?fv| zsJ+k&2c@_XYlnTdlI=p{{mM>uvca(!n1k*Ni~xn8=DHl-Q}5orL$I3eU571r|M{4u zzSAri3hVq;W;&@tEN2#%VJX@!gyqq8KZUCWysT&`EKO^qV`x3SrK=s*hC@R`Fd5(U zzEyNwG|ze3MK=Gva^7`biW1g@5iDjd7h!F($E>@UU(WF>DJ8mBx*R0jz)-)jr=lWQrQ=7oc0)M;(^;fJ*!w1C(mkDk0%yY*_$=(ep@;7Xn- zBPwmuV(oIw=s1CI$^^H{)ZqpDQNZOac-dl{YHNG{9C~WSt_TM{vky#Wgay7k;)_a{ z$qg49!tPgT1<*iF2xzMWx64&I8GIepyvH)rCoLA7g3c{0y3oL+`4rwbkw zWr9>c@YxBao2UKGo;!K6@%)+~b0gRFN6K@WE>>MX?SH32BghI|XM^4gz-2EunY%VH zs;ueEp;Ha%Y9?`$3u}zPo5Wo>eXRSGvg2;h&jD`x!If-qF&*TDVeePz)TF9DJ1z3| zJYX}yU?b?R8(HD`X|Zc(Sqpa`LH+-%Nf4q2p{%5eo2PxdPpQUxfJ6QxYCdFGB#k}~ zGy-1=$Yy{iCq*xm?McrmMuwrd5eo^a8DVZA#W&7}Hx(~xsS=NN0nbhWKPsq60Jrja zt`!p+Ypfzu3a2fJLDuJLtRGtydTSGH1B&8Pv)Js^qJo69qiH@Y_WT`b@IN+x!`~#Q r;!k2t#T3>Q))dwh))dwh)>QleYz>G3Cr&X#00000NkvXXu0mjfo>#oa literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/vi.png b/lib/src/assets/flags/vi.png new file mode 100644 index 0000000000000000000000000000000000000000..e9127a84a3424b0aadb7f3da30018e1984452445 GIT binary patch literal 6402 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 Q)Bpeg07*qoM6N<$f>I!BX#fBK literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/vn.png b/lib/src/assets/flags/vn.png new file mode 100644 index 0000000000000000000000000000000000000000..cbf65d4163206c17b39e49dbe902cd8162d7468d GIT binary patch literal 723 zcmV;^0xbQBP)0{{R3U6oMi0003&P)t-s+9e&@ zCLP)*9oi@z+A1B}C>`4=9NQ@!+bSH}D;(P_9NR4%+b$g3H5=VD8{IV<-8UNDHyhnJ z8s0h@-aH!KKN{XZ8Q(z};7J(ZOBmrz7~xJB<5w2rSr+437UNqM<6RczWfbLR73g>p z=z0<8dJ^b+5$c2x>V**Ni4g0G5bKK%>x~cWix2FL5A2Q)?UfGgmJaTg4(^-{?wt+p zpAGMz4DX^0@S+UxsSNO{3-PQA@vRH=z6tcd2=&7V^~4DE#R&Dt2lmAX_Q(hJ$p`kz z2lvef_s<6R&<6L=2l&zk_|pdX)du<41^L?r`P~Hh-39sH1o_?t`rZWk-Ua&K1p43v z`r!on;{^KT1N-9y`{V@s|Ie5d+&-Ed$Rxk1B}6O zB%nTU?u&ERf~IMjCZ*B`^~NGl@8lTDm0DIARO=a_7w8w43M$?MCr!-M_Z?alalEWuBS*m`_( zdvE{X@a*z7Icp#{^EUrr&l$*7;F-UAZij&KRsLe70y4T@`GeOkh-o-tR>yt_%Ad5E z!Ja6Dte{B`GYD~2ai)p;puh;zgrUMY)0{$qMtb-mZgihH1Gnx<+0%R57#y)!&Ew*deE002ovPDHLk FV1oVeUeW*n literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/vu.png b/lib/src/assets/flags/vu.png new file mode 100644 index 0000000000000000000000000000000000000000..58764567366fba8042e26090605d140c02ba6283 GIT binary patch literal 1835 zcmV+`2h{k9P)?(y3Mm>mm6grT{`5C;s1O~y|Ky* z*{Z*drZq%gWI;rH#vQxTNyxxg#q#l^K2&e5_CmJ!H@$8}5quQJNiTWgR-5G<3X7^t zVSdu*ng!YH@3m^B1@KW6C%@%MSeMt4!GBhjlESR-v=ms>Q@+&77iAzz;9c)4iR&B- zi>h`7aly~J1=*O7)Dro5@KHhD{h5+~y<=ffHLfPE_{$3!PSU^MQ47U0kQL*VZ`Fe9 z9Se)9bscHl2qP`Bo2vqUepN|`;us5`p#H2DaxN?sA<((8v~{c(GOW?QeqMD>FJu>&1ibx_ zC(t0^qXuHYSglxIhK2p3t`JCHvILKIa~+-Kh3xFYfR_ik4VC!ji_N8=NqUJq1*>{# z0ZaLF3zK4rgVRl%V$4;E%Htx>_I00}>lI_*AD`*tQry1zB55lHPuEM@9#(8PH{YkQ zqQ17`{z5KGke+mfygJx@cA*zCeCQtO>T*d|WFn9*a_DTmlwD!PgmFh^CQYa_3j&6{ zr{V)O@&h&P_~-nfTXYLWWD*p!TvPf<-dndduMpjMDall~Sya{aDq~ zELHgX-``YIM*hKL9>_?zEq?lx=khWyWVnI$YRSkKB|_?mCbs3+X68;ann5}wEX@gl zsIXL6;lYFucxj+JrF_Q}3^E~H=DvABxw_nII&T?cbZR7V9N1X6<>N?jQO6w+(KM(c zKHb|D70Nx*-GxD*zyo^qKS|~2^ZneAX<>=~>+6aoEW>7?RUL^Cu%+;U!ZD0^Uxj2f zt0Ao$uJ>;vL$bOwk?2roeyc$iRXCpi=Uw%tH?rk_>W!+3_Cq%All!o6uF*dR=;WXG z)IP1HKi^hTCSAceo(>W_9>|tT7U1ynexY4O+BRK#Rz1f8;1LJm}+m@xG#nlIYG_o)`Kj zZHV)J(j7ewX_rH{c^nT0dz6gysvwVL7dAS7y{!&tD;p}o zT|e#N7$K0!qV(Grm1`@kMQO)|?4s1(s#i(GIAPnk)MymvDXu%&Yj<`{G<&vSv^yYh zP%;F%6oy{Ka;Y;TdHSm9f$bQLG>9D3kAwGW!dLZjwX+Iq z^BAL2aRDI95zWJ_hz0}>YRACa)h*way zYJF({Gru-;y-QHXwA0tmKm7ap z?eEj)zjjRgv10wFl>DFDc7HCa{keV5$MBT@fByde`Rl!d-+KrD|G$2H@Qz^o^5GuP zQnr#HzurJY5_^Dj45h3{5)fz|s0pTQKd>)g5o^C%(PRxsp5N zr}+oP_SoaXuVpqIGWb!^-XSi0x-x9ium1E7#Wsl~5b?<+a-VjvW7njJ)P+qBjf%Y? zK8=C4tuY_;)<;}7UvvAG{i@7`2Q+pqpYX4@vgHl~tJ}+YPJfOUv#_$AR1QecP(Z?p zCVv0+RVx0vJA1`{7Ps3@g6;`C%p!#>Y=R<%DaK~5Qke+`ONHIEBz#u32&NghN;NXN uvPOQ6U2XHp-0s)j?tGKUS9H4A-|uvc z#^&nv`TG6;|NrUj_JWwqgPF|g?e^#E_1fU@JzuX)Y_`YI=xv6>Em5gbaJXH0yk2^} zEmEm(h{Qf$us2$*f|twT=JVs|^TyEV`uqLD&E_~-t+T=4Ol!3+Q>pUw`gV=S^!EBY zU9a`_`-GXzv%uhel*+}==flnBn5xx3V6aYYwnSvISarKucDqk)w?JXB#Lnl^+U?}% z^y269dy>h~+3aqI!>_&Gg__NWoX#&(s&I(J)7$N9g~C5!uu5sQOKP=jhQr+A@!R3> zGF7Yh`TUir)b{xMCQPGDUy?9Xs+p_Rm#NhF`TSdVyedtjlZ9@XiEGfNP+w|@TzI@% zce_4Vn3#xcvX)*dO`?o}aloEfdU$&)PNF4Cq@RpvznxfQY=(w^bvRXqq)|m&lulrfR%MJxUX(IYo?&Z;e0h3+e0a8)T_#GUC`_ZOl48rFQ-XYVaC3i@ zg>F(~kC23KO<<93ae$zWXpDk#TW5+>WR5IPp*&ZaE>NIGT$L$JqHA!0$e~oLl4Hc5 zR$gg{$)Z$BUXo{RgkWii&ZSY7hiz(bgTbCxS7nSgRGg!ZWdv~#xUqf1!5U{bW%=JvSo=1#sB~Uvq?ljRCodGkb{x~ zVGss0huFz?j&0kv@&1o;|DFe6ZVW{#Qo=fx})4fi=i(2SRip3`E319*jZ|i<2N8e?`QgAx546kYr1x zFEZI2+f6=GNT=9r0E%j2N`_ZN$`v|L1yEzD*NGZUw$?FGyUo@CP`!J;`_f3M*9Qi@ zq0rGdHJQ=_%qH_iPfl{pvJdo^CHadc8AGrVl3I)1h8|$c)6B(g2Z8UUziSWZ=>?d8 zTZNMvClQfRHqm}qBmjzu#i~9oGCmRjX=Gf~Q9q_G>LFceO5mkcu0$bGwN{@I zc{6(PLybFkjrYbyB6J^LdT^Kr9zIfZ$G13O)?GvqAVT7i3rW0B|F}#Z%-RCGAIZf*|52RRVRUwJL16p zmg^UO&a#b+&`aAG;dT1(C&TWeK~a3udLwnFT{^_O>_O6r=F8$~KqDADUHx3vIVCg! E0HU!r+yDRo literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/yt.png b/lib/src/assets/flags/yt.png new file mode 100644 index 0000000000000000000000000000000000000000..6a196cb7e81ab28402ae0480a009aa982e627ec6 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^DM0MZ!VDy5r0#tQq~rp8LR>YS7HwO7_RoVy-&d}G zt7*xgJazTB?YoVtS$F#Q65KAumvlN#XZ$v*z{9@~(j*u7OkTFVg6mv{PhjuliEfUB|8g6)1^@s6YD=Kn0006$NklYzd+!&XZgB7D>@#bhwf^P9%wE6o zs6yF;L}mG_NX`(+Ik-x`{rn-Jj_0~^f7xp1SjS%9jO@3puQpvYhg9zrc3gZ$~+u8IPrg@fpTv~ZAAYRNvZl3GHf zF3v3@dI)MUpDIyIN#4j(;_NCf)M7sM`^cYK)GR900y2n>TEGUO7SKVomi$rF0yBuN zWi4s}7=&6N2B8+XLG0I}&&R#H<-?Ax))jaVY%TU5|AXLb;UI`wI0%3i-H?^}e}}pF z?4Gsx7$mrsOR;NVi5^62DHv^53kRVV{6VM%a1d$%9fVo{2hol1UqX)%vU!W^bC94> z2=7BU2vzWT2m@2Wz*MkwQZaN@0blLq`yq)v%4QY%J12a{kSY)c@vkCtj(HU;w_TS- z8?IQFN~DSt>nlrrgDNiFcr7i5ZWL8xw!Ni;3dixJV9qHiQE#5TL+GdiEUEx2^!G!k z!dM|bTSXNnqYAL70xYTkiz>iMwTebm5xG>W`0o6qib$nO#p%bl{HS1HDwru17q5p@ z!Az*gpB+{O15?4kR4_0V3`_+BQ^5*lCr*Xydfv39=U=zmnYqxX- RSI+1^@s6YD=Kn0009?NklDu-^Twzfs$EP%|ik+Cj~jAL68O5!N=t+O~D}-TL;e!g5n%o>8pd%)E&H zw$96bH!>+Ullk3SGQ*may-BMb5kE1MiO!9NoYt8@J%r%ZCphnzmh`ZI(s0sz}jbK?{@ zOmp^oY&Q4Jc%e&DXZsQM8({AV)(vpn5Eob69qzt+&o*h*l~^xT2uptgjSo{EMkfYAJ$ob!3Btb z=x^%;8SwWe`;GGdNtOjxR`};4-W~-yJxVFdD||Y`2Fs}CXwGxnIQuMQwtrw)vb4l_lTwaqfyp{6sw^on+NPW%^r++s=mdu9d@{$PJa6Z@r^Zu@=*9qj{jxHl z&C)tYwdhT;bxN;GHD*bk-aNG;5#Dc-b_p@LK%+&W$V`_HQtqno(o#Z<1mMR7$@B<4 zmdvuO%}SiurZmrgt2{cvmNgnp+C7F_yorGh5B-hNMM(XCA0H$W2yJ%xfJ=+4Nm-NQ z+9?zW9Y!kLTBcjmw^ZiGiHPzH7I?DF>k-d27>K!LB_SqCv#pa~)v^``m)L(fheiBt zA*CWxq7_D$`7D|Y!Hr(cJ6XT13Fyna1$9-Ef4Usg7TeAXUa z8z2-!0RVfryYD{}10W?0?(kQ*{*o1f5FrQ=f)IoVL5L892tkMtgdju+LWCeh2ttG) z1R+8YA_O5q5F!L22oZu1AqWwIkStUqVjUSfHUF#q;M<8r-+R2P)2KzFLpi?NQdA;Q Y0SE~hlnzXQR{#J207*qoM6N<$f_%k~YybcN literal 0 HcmV?d00001 diff --git a/lib/src/assets/flags/zw.png b/lib/src/assets/flags/zw.png new file mode 100644 index 0000000000000000000000000000000000000000..f502027995247a38cf38b3316ee0fdc01a17d9ad GIT binary patch literal 1472 zcmV;x1wZGHIxX#|?;9t9|B~r#Hq-Ec}XxYIs~|hsOB|P$jV}hH*$G971ll8@7_`SI>U)VV?a* zEXxPWvJAtV9$O6!UE8*}ni_qTtlGbC*NqpBY|r7Lsu7`+z_Oe+ov!vB?JrLmdcH>t zqj~ZPIT5CP<|$D1`&ROS2Oe0nG%V%P@yct$RQ|d8tkf~>WXY#R=wEq}L&$$CSzTSdbNlv7!p2IcN5JOtA?QebbHI2lv-* zTd7MCAZTJ=B$PdetiLH5=9gmL6va8>?gRVPH{PIo;dygvs;jn^QLB*0W3^iQDwznC z3`$vacX!X_m&qoLlkq3Wsj$8eG%ksrfYJvx6fb$R%>n<9cLr)$VM9NL#(YM&vL`zB7^ib!i32@6V_MKFH8yzfaQ z8n#3!W_v#kKEHj2K>PB`tliG}QD5J%apR^DBS!Fo3C<6DNm0k@RqZpp+rFl~QPw=t zT1e7mWN$j*C?fqU=_=tj-^p*C8Kqdg%2_Gl0%5b+?z-!)@#Dt_r!0Wc>(sa3uAn02 zPYSHXq`k=7M7Dy`W)reRQP(MvDUX16vgH(#P|7bBTe@1g0fCDk6h#H6EH5mpP5jE1 zErbGs6j(>LBC;((*q$uXWD(XP?{ZUT5Xv-BPnt-Ud!^ZI3|(1(uHk)cw#ZgULi>8s zh^|yoXR6m!ZyEvrYcjpjWfP9lXiZBjhfs*tun$$mb;@+1qnK1@60TCxT}mm_34IO$ zHMHcDEEH2hG3AsxXP(8N1L> zN=33rS$r`~yE%V?eAgim`tD|X=^PmChHRqgq*oBAfo-BPjp+GK1Op3JoGOFp{^@n@ zOoDxa0AUe))cEZ;2%r4(`WPI1T6xIe3l@WeFNF;Qe32Dj zzQ;F);9HLV-Qb(qh7o+5G7!2NSK;Oca`#~*(j-`b5I8o-aE;0K-XBXs}o;D 'lib/src/assets/flags/${isoCode.toLowerCase()}.png'; + + @override + String toString() => { + 'dialCode': dialCode, + 'name': name, + 'isoCode': isoCode, + }.toString(); +} + +/// [Countries] +class Countries { + /// List of [Country] for most countries around the world. + static List get list => _countriesList; + static final List _countriesList = [ + const Country( + isoCode: 'AF', + name: 'Afghanistan', + dialCode: '+93', + ), + const Country( + isoCode: 'AX', + name: 'Ã…land Islands', + dialCode: '+358', + ), + const Country( + isoCode: 'AL', + name: 'Albania', + dialCode: '+355', + ), + const Country( + isoCode: 'DZ', + name: 'Algeria', + dialCode: '+213', + ), + const Country( + isoCode: 'AS', + name: 'American Samoa', + dialCode: '+1684', + ), + const Country( + isoCode: 'AD', + name: 'Andorra', + dialCode: '+376', + ), + const Country( + isoCode: 'AO', + name: 'Angola', + dialCode: '+244', + ), + const Country( + isoCode: 'AI', + name: 'Anguilla', + dialCode: '+1264', + ), + const Country( + isoCode: 'AQ', + name: 'Antarctica', + dialCode: '+672', + ), + const Country( + isoCode: 'AG', + name: 'Antigua and Barbuda', + dialCode: '+1268', + ), + const Country( + isoCode: 'AR', + name: 'Argentina', + dialCode: '+54', + ), + const Country( + isoCode: 'AM', + name: 'Armenia', + dialCode: '+374', + ), + const Country( + isoCode: 'AW', + name: 'Aruba', + dialCode: '+297', + ), + const Country( + isoCode: 'AU', + name: 'Australia', + dialCode: '+61', + ), + const Country( + isoCode: 'AT', + name: 'Austria', + dialCode: '+43', + ), + const Country( + isoCode: 'AZ', + name: 'Azerbaijan', + dialCode: '+994', + ), + const Country( + isoCode: 'BS', + name: 'Bahamas', + dialCode: '+1242', + ), + const Country( + isoCode: 'BH', + name: 'Bahrain', + dialCode: '+973', + ), + const Country( + isoCode: 'BD', + name: 'Bangladesh', + dialCode: '+880', + ), + const Country( + isoCode: 'BB', + name: 'Barbados', + dialCode: '+1246', + ), + const Country( + isoCode: 'BY', + name: 'Belarus', + dialCode: '+375', + ), + const Country( + isoCode: 'BE', + name: 'Belgium', + dialCode: '+32', + ), + const Country( + isoCode: 'BZ', + name: 'Belize', + dialCode: '+501', + ), + const Country( + isoCode: 'BJ', + name: 'Benin', + dialCode: '+229', + ), + const Country( + isoCode: 'BM', + name: 'Bermuda', + dialCode: '+1441', + ), + const Country( + isoCode: 'BT', + name: 'Bhutan', + dialCode: '+975', + ), + const Country( + isoCode: 'BO', + name: 'Bolivia (Plurinational State of)', + dialCode: '+591', + ), + const Country( + isoCode: 'BA', + name: 'Bosnia and Herzegovina', + dialCode: '+387', + ), + const Country( + isoCode: 'BW', + name: 'Botswana', + dialCode: '+267', + ), + const Country( + isoCode: 'BR', + name: 'Brazil', + dialCode: '+55', + ), + const Country( + isoCode: 'IO', + name: 'British Indian Ocean Territory', + dialCode: '+246', + ), + const Country( + isoCode: 'BN', + name: 'Brunei Darussalam', + dialCode: '+673', + ), + const Country( + isoCode: 'BG', + name: 'Bulgaria', + dialCode: '+359', + ), + const Country( + isoCode: 'BF', + name: 'Burkina Faso', + dialCode: '+226', + ), + const Country( + isoCode: 'BI', + name: 'Burundi', + dialCode: '+257', + ), + const Country( + isoCode: 'CV', + name: 'Cabo Verde', + dialCode: '+238', + ), + const Country( + isoCode: 'KH', + name: 'Cambodia', + dialCode: '+855', + ), + const Country( + isoCode: 'CM', + name: 'Cameroon', + dialCode: '+237', + ), + const Country( + isoCode: 'CA', + name: 'Canada', + dialCode: '+1', + ), + const Country( + isoCode: 'KY', + name: 'Cayman Islands', + dialCode: '+1345', + ), + const Country( + isoCode: 'CF', + name: 'Central African Republic', + dialCode: '+236', + ), + const Country( + isoCode: 'TD', + name: 'Chad', + dialCode: '+235', + ), + const Country( + isoCode: 'CL', + name: 'Chile', + dialCode: '+56', + ), + const Country( + isoCode: 'CN', + name: 'China', + dialCode: '+86', + ), + const Country( + isoCode: 'CX', + name: 'Christmas Island', + dialCode: '+61', + ), + const Country( + isoCode: 'CC', + name: 'Cocos (Keeling) Islands', + dialCode: '+61', + ), + const Country( + isoCode: 'CO', + name: 'Colombia', + dialCode: '+57', + ), + const Country( + isoCode: 'KM', + name: 'Comoros', + dialCode: '+269', + ), + const Country( + isoCode: 'CG', + name: 'Congo (Republic of the)', + dialCode: '+242', + ), + const Country( + isoCode: 'CD', + name: 'Congo (Democratic Republic of the)', + dialCode: '+243', + ), + const Country( + isoCode: 'CK', + name: 'Cook Islands', + dialCode: '+682', + ), + const Country( + isoCode: 'CR', + name: 'Costa Rica', + dialCode: '+506', + ), + const Country( + isoCode: 'CI', + name: 'Côte d`Ivoire', + dialCode: '+225', + ), + const Country( + isoCode: 'HR', + name: 'Croatia', + dialCode: '+385', + ), + const Country( + isoCode: 'CU', + name: 'Cuba', + dialCode: '+53', + ), + const Country( + isoCode: 'CY', + name: 'Cyprus', + dialCode: '+357', + ), + const Country( + isoCode: 'CZ', + name: 'Czech Republic', + dialCode: '+420', + ), + const Country( + isoCode: 'DK', + name: 'Denmark', + dialCode: '+45', + ), + const Country( + isoCode: 'DJ', + name: 'Djibouti', + dialCode: '+253', + ), + const Country( + isoCode: 'DM', + name: 'Dominica', + dialCode: '+1767', + ), + const Country( + isoCode: 'DO', + name: 'Dominican Republic', + dialCode: '+1', + ), + const Country( + isoCode: 'EC', + name: 'Ecuador', + dialCode: '+593', + ), + const Country( + isoCode: 'EG', + name: 'Egypt', + dialCode: '+20', + ), + const Country( + isoCode: 'SV', + name: 'El Salvador', + dialCode: '+503', + ), + const Country( + isoCode: 'GQ', + name: 'Equatorial Guinea', + dialCode: '+240', + ), + const Country( + isoCode: 'ER', + name: 'Eritrea', + dialCode: '+291', + ), + const Country( + isoCode: 'EE', + name: 'Estonia', + dialCode: '+372', + ), + const Country( + isoCode: 'ET', + name: 'Ethiopia', + dialCode: '+251', + ), + const Country( + isoCode: 'FK', + name: 'Falkland Islands (Malvinas)', + dialCode: '+500', + ), + const Country( + isoCode: 'FO', + name: 'Faroe Islands', + dialCode: '+298', + ), + const Country( + isoCode: 'FJ', + name: 'Fiji', + dialCode: '+679', + ), + const Country( + isoCode: 'FI', + name: 'Finland', + dialCode: '+358', + ), + const Country( + isoCode: 'FR', + name: 'France', + dialCode: '+33', + ), + const Country( + isoCode: 'GF', + name: 'French Guiana', + dialCode: '+594', + ), + const Country( + isoCode: 'PF', + name: 'French Polynesia', + dialCode: '+689', + ), + const Country( + isoCode: 'TF', + name: 'French Southern Territories', + dialCode: '+262', + ), + const Country( + isoCode: 'GA', + name: 'Gabon', + dialCode: '+241', + ), + const Country( + isoCode: 'GM', + name: 'Gambia', + dialCode: '+220', + ), + const Country( + isoCode: 'GE', + name: 'Georgia', + dialCode: '+995', + ), + const Country( + isoCode: 'DE', + name: 'Germany', + dialCode: '+49', + ), + const Country( + isoCode: 'GH', + name: 'Ghana', + dialCode: '+233', + ), + const Country( + isoCode: 'GI', + name: 'Gibraltar', + dialCode: '+350', + ), + const Country( + isoCode: 'GR', + name: 'Greece', + dialCode: '+30', + ), + const Country( + isoCode: 'GL', + name: 'Greenland', + dialCode: '+299', + ), + const Country( + isoCode: 'GD', + name: 'Grenada', + dialCode: '+1473', + ), + const Country( + isoCode: 'GP', + name: 'Guadeloupe', + dialCode: '+590', + ), + const Country( + isoCode: 'GU', + name: 'Guam', + dialCode: '+1671', + ), + const Country( + isoCode: 'GT', + name: 'Guatemala', + dialCode: '+502', + ), + const Country( + isoCode: 'GN', + name: 'Guinea', + dialCode: '+224', + ), + const Country( + isoCode: 'GW', + name: 'Guinea-Bissau', + dialCode: '+245', + ), + const Country( + isoCode: 'GY', + name: 'Guyana', + dialCode: '+592', + ), + const Country( + isoCode: 'HT', + name: 'Haiti', + dialCode: '+509', + ), + const Country( + isoCode: 'HM', + name: 'Heard Island and McDonald Islands', + dialCode: '+0', + ), + const Country( + isoCode: 'VA', + name: 'Vatican City State', + dialCode: '+379', + ), + const Country( + isoCode: 'HN', + name: 'Honduras', + dialCode: '+504', + ), + const Country( + isoCode: 'HK', + name: 'Hong Kong', + dialCode: '+852', + ), + const Country( + isoCode: 'HU', + name: 'Hungary', + dialCode: '+36', + ), + const Country( + isoCode: 'IS', + name: 'Iceland', + dialCode: '+354', + ), + const Country( + isoCode: 'IN', + name: 'India', + dialCode: '+91', + ), + const Country( + isoCode: 'ID', + name: 'Indonesia', + dialCode: '+62', + ), + const Country( + isoCode: 'IR', + name: 'Iran', + dialCode: '+98', + ), + const Country( + isoCode: 'IQ', + name: 'Iraq', + dialCode: '+964', + ), + const Country( + isoCode: 'IE', + name: 'Ireland', + dialCode: '+353', + ), + const Country( + isoCode: 'IL', + name: 'Israel', + dialCode: '+972', + ), + const Country( + isoCode: 'IT', + name: 'Italy', + dialCode: '+39', + ), + const Country( + isoCode: 'JM', + name: 'Jamaica', + dialCode: '+1876', + ), + const Country( + isoCode: 'JP', + name: 'Japan', + dialCode: '+81', + ), + const Country( + isoCode: 'JO', + name: 'Jordan', + dialCode: '+962', + ), + const Country( + isoCode: 'KZ', + name: 'Kazakhstan', + dialCode: '+7', + ), + const Country( + isoCode: 'KE', + name: 'Kenya', + dialCode: '+254', + ), + const Country( + isoCode: 'KI', + name: 'Kiribati', + dialCode: '+686', + ), + const Country( + isoCode: 'XK', + name: 'Kosovo (Republic of)', + dialCode: '+383', + ), + const Country( + isoCode: 'KP', + name: 'Korea (Democratic People`s Republic of)', + dialCode: '+850', + ), + const Country( + isoCode: 'KR', + name: 'Korea (Republic of)', + dialCode: '+82', + ), + const Country( + isoCode: 'KW', + name: 'Kuwait', + dialCode: '+965', + ), + const Country( + isoCode: 'KG', + name: 'Kyrgyzstan', + dialCode: '+996', + ), + const Country( + isoCode: 'LA', + name: 'Lao People`s Democratic Republic', + dialCode: '+856', + ), + const Country( + isoCode: 'LV', + name: 'Latvia', + dialCode: '+371', + ), + const Country( + isoCode: 'LB', + name: 'Lebanon', + dialCode: '+961', + ), + const Country( + isoCode: 'LS', + name: 'Lesotho', + dialCode: '+266', + ), + const Country( + isoCode: 'LR', + name: 'Liberia', + dialCode: '+231', + ), + const Country( + isoCode: 'LY', + name: 'Libya', + dialCode: '+218', + ), + const Country( + isoCode: 'LI', + name: 'Liechtenstein', + dialCode: '+423', + ), + const Country( + isoCode: 'LT', + name: 'Lithuania', + dialCode: '+370', + ), + const Country( + isoCode: 'LU', + name: 'Luxembourg', + dialCode: '+352', + ), + const Country( + isoCode: 'MO', + name: 'Macao', + dialCode: '+853', + ), + const Country( + isoCode: 'MK', + name: 'Macedonia (the former Yugoslav Republic of)', + dialCode: '+389', + ), + const Country( + isoCode: 'MG', + name: 'Madagascar', + dialCode: '+261', + ), + const Country( + isoCode: 'MW', + name: 'Malawi', + dialCode: '+265', + ), + const Country( + isoCode: 'MY', + name: 'Malaysia', + dialCode: '+60', + ), + const Country( + isoCode: 'MV', + name: 'Maldives', + dialCode: '+960', + ), + const Country( + isoCode: 'ML', + name: 'Mali', + dialCode: '+223', + ), + const Country( + isoCode: 'MT', + name: 'Malta', + dialCode: '+356', + ), + const Country( + isoCode: 'MH', + name: 'Marshall Islands', + dialCode: '+692', + ), + const Country( + isoCode: 'MQ', + name: 'Martinique', + dialCode: '+596', + ), + const Country( + isoCode: 'MR', + name: 'Mauritania', + dialCode: '+222', + ), + const Country( + isoCode: 'MU', + name: 'Mauritius', + dialCode: '+230', + ), + const Country( + isoCode: 'YT', + name: 'Mayotte', + dialCode: '+262', + ), + const Country( + isoCode: 'MX', + name: 'Mexico', + dialCode: '+52', + ), + const Country( + isoCode: 'FM', + name: 'Micronesia (Federated States of)', + dialCode: '+691', + ), + const Country( + isoCode: 'MD', + name: 'Moldova (Republic of)', + dialCode: '+373', + ), + const Country( + isoCode: 'MC', + name: 'Monaco', + dialCode: '+377', + ), + const Country( + isoCode: 'MN', + name: 'Mongolia', + dialCode: '+976', + ), + const Country( + isoCode: 'ME', + name: 'Montenegro', + dialCode: '+382', + ), + const Country( + isoCode: 'MS', + name: 'Montserrat', + dialCode: '+1664', + ), + const Country( + isoCode: 'MA', + name: 'Morocco', + dialCode: '+212', + ), + const Country( + isoCode: 'MZ', + name: 'Mozambique', + dialCode: '+258', + ), + const Country( + isoCode: 'MM', + name: 'Myanmar', + dialCode: '+95', + ), + const Country( + isoCode: 'NA', + name: 'Namibia', + dialCode: '+264', + ), + const Country( + isoCode: 'NR', + name: 'Nauru', + dialCode: '+674', + ), + const Country( + isoCode: 'NP', + name: 'Nepal', + dialCode: '+977', + ), + const Country( + isoCode: 'NL', + name: 'Netherlands', + dialCode: '+31', + ), + const Country( + isoCode: 'NC', + name: 'New Caledonia', + dialCode: '+687', + ), + const Country( + isoCode: 'NZ', + name: 'New Zealand', + dialCode: '+64', + ), + const Country( + isoCode: 'NI', + name: 'Nicaragua', + dialCode: '+505', + ), + const Country( + isoCode: 'NE', + name: 'Niger', + dialCode: '+227', + ), + const Country( + isoCode: 'NG', + name: 'Nigeria', + dialCode: '+234', + ), + const Country( + isoCode: 'NU', + name: 'Niue', + dialCode: '+683', + ), + const Country( + isoCode: 'NF', + name: 'Norfolk Island', + dialCode: '+672', + ), + const Country( + isoCode: 'MP', + name: 'Northern Mariana Islands', + dialCode: '+1670', + ), + const Country( + isoCode: 'NO', + name: 'Norway', + dialCode: '+47', + ), + const Country( + isoCode: 'OM', + name: 'Oman', + dialCode: '+968', + ), + const Country( + isoCode: 'PK', + name: 'Pakistan', + dialCode: '+92', + ), + const Country( + isoCode: 'PW', + name: 'Palau', + dialCode: '+680', + ), + const Country( + isoCode: 'PS', + name: 'Palestine, State of', + dialCode: '+970', + ), + const Country( + isoCode: 'PA', + name: 'Panama', + dialCode: '+507', + ), + const Country( + isoCode: 'PG', + name: 'Papua New Guinea', + dialCode: '+675', + ), + const Country( + isoCode: 'PY', + name: 'Paraguay', + dialCode: '+595', + ), + const Country( + isoCode: 'PE', + name: 'Peru', + dialCode: '+51', + ), + const Country( + isoCode: 'PH', + name: 'Philippines', + dialCode: '+63', + ), + const Country( + isoCode: 'PN', + name: 'Pitcairn', + dialCode: '+64', + ), + const Country( + isoCode: 'PL', + name: 'Poland', + dialCode: '+48', + ), + const Country( + isoCode: 'PT', + name: 'Portugal', + dialCode: '+351', + ), + const Country( + isoCode: 'PR', + name: 'Puerto Rico', + dialCode: '+1939', + ), + const Country( + isoCode: 'QA', + name: 'Qatar', + dialCode: '+974', + ), + const Country( + isoCode: 'RE', + name: 'Réunion', + dialCode: '+262', + ), + const Country( + isoCode: 'RO', + name: 'Romania', + dialCode: '+40', + ), + const Country( + isoCode: 'RU', + name: 'Russian Federation', + dialCode: '+7', + ), + const Country( + isoCode: 'RW', + name: 'Rwanda', + dialCode: '+250', + ), + const Country( + isoCode: 'BL', + name: 'Saint Barthélemy', + dialCode: '+590', + ), + const Country( + isoCode: 'SH', + name: 'Saint Helena, Ascension and Tristan da Cunha', + dialCode: '+290', + ), + const Country( + isoCode: 'KN', + name: 'Saint Kitts and Nevis', + dialCode: '+1869', + ), + const Country( + isoCode: 'LC', + name: 'Saint Lucia', + dialCode: '+1758', + ), + const Country( + isoCode: 'MF', + name: 'Saint Martin (French part)', + dialCode: '+590', + ), + const Country( + isoCode: 'PM', + name: 'Saint Pierre and Miquelon', + dialCode: '+508', + ), + const Country( + isoCode: 'VC', + name: 'Saint Vincent and the Grenadines', + dialCode: '+1784', + ), + const Country( + isoCode: 'WS', + name: 'Samoa', + dialCode: '+685', + ), + const Country( + isoCode: 'SM', + name: 'San Marino', + dialCode: '+378', + ), + const Country( + isoCode: 'ST', + name: 'Sao Tome and Principe', + dialCode: '+239', + ), + const Country( + isoCode: 'SA', + name: 'Saudi Arabia', + dialCode: '+966', + ), + const Country( + isoCode: 'SN', + name: 'Senegal', + dialCode: '+221', + ), + const Country( + isoCode: 'RS', + name: 'Serbia', + dialCode: '+381', + ), + const Country( + isoCode: 'SC', + name: 'Seychelles', + dialCode: '+248', + ), + const Country( + isoCode: 'SL', + name: 'Sierra Leone', + dialCode: '+232', + ), + const Country( + isoCode: 'SG', + name: 'Singapore', + dialCode: '+65', + ), + const Country( + isoCode: 'SK', + name: 'Slovakia', + dialCode: '+421', + ), + const Country( + isoCode: 'SI', + name: 'Slovenia', + dialCode: '+386', + ), + const Country( + isoCode: 'SB', + name: 'Solomon Islands', + dialCode: '+677', + ), + const Country( + isoCode: 'SO', + name: 'Somalia', + dialCode: '+252', + ), + const Country( + isoCode: 'ZA', + name: 'South Africa', + dialCode: '+27', + ), + const Country( + isoCode: 'GS', + name: 'South Georgia and the South Sandwich Islands', + dialCode: '+500', + ), + const Country( + isoCode: 'SS', + name: 'South Sudan', + dialCode: '+211', + ), + const Country( + isoCode: 'ES', + name: 'Spain', + dialCode: '+34', + ), + const Country( + isoCode: 'LK', + name: 'Sri Lanka', + dialCode: '+94', + ), + const Country( + isoCode: 'SD', + name: 'Sudan', + dialCode: '+249', + ), + const Country( + isoCode: 'SR', + name: 'Suriname', + dialCode: '+597', + ), + const Country( + isoCode: 'SZ', + name: 'Swaziland', + dialCode: '+268', + ), + const Country( + isoCode: 'SE', + name: 'Sweden', + dialCode: '+46', + ), + const Country( + isoCode: 'CH', + name: 'Switzerland', + dialCode: '+41', + ), + const Country( + isoCode: 'SY', + name: 'Syrian Arab Republic', + dialCode: '+963', + ), + const Country( + isoCode: 'TW', + name: 'Taiwan', + dialCode: '+886', + ), + const Country( + isoCode: 'TJ', + name: 'Tajikistan', + dialCode: '+992', + ), + const Country( + isoCode: 'TZ', + name: 'Tanzania, United Republic of', + dialCode: '+255', + ), + const Country( + isoCode: 'TH', + name: 'Thailand', + dialCode: '+66', + ), + const Country( + isoCode: 'TL', + name: 'Timor-Leste', + dialCode: '+670', + ), + const Country( + isoCode: 'TG', + name: 'Togo', + dialCode: '+228', + ), + const Country( + isoCode: 'TK', + name: 'Tokelau', + dialCode: '+690', + ), + const Country( + isoCode: 'TO', + name: 'Tonga', + dialCode: '+676', + ), + const Country( + isoCode: 'TT', + name: 'Trinidad and Tobago', + dialCode: '+1868', + ), + const Country( + isoCode: 'TN', + name: 'Tunisia', + dialCode: '+216', + ), + const Country( + isoCode: 'TR', + name: 'Turkey', + dialCode: '+90', + ), + const Country( + isoCode: 'TM', + name: 'Turkmenistan', + dialCode: '+993', + ), + const Country( + isoCode: 'TC', + name: 'Turks and Caicos Islands', + dialCode: '+1649', + ), + const Country( + isoCode: 'TV', + name: 'Tuvalu', + dialCode: '+688', + ), + const Country( + isoCode: 'UG', + name: 'Uganda', + dialCode: '+256', + ), + const Country( + isoCode: 'UA', + name: 'Ukraine', + dialCode: '+380', + ), + const Country( + isoCode: 'AE', + name: 'United Arab Emirates', + dialCode: '+971', + ), + const Country( + isoCode: 'GB', + name: 'Great Britain and Northern Ireland', + dialCode: '+44', + ), + const Country( + isoCode: 'US', + name: 'United States of America', + dialCode: '+1', + ), + const Country( + isoCode: 'UY', + name: 'Uruguay', + dialCode: '+598', + ), + const Country( + isoCode: 'UZ', + name: 'Uzbekistan', + dialCode: '+998', + ), + const Country( + isoCode: 'VU', + name: 'Vanuatu', + dialCode: '+678', + ), + const Country( + isoCode: 'VE', + name: 'Venezuela (Bolivarian Republic of)', + dialCode: '+58', + ), + const Country( + isoCode: 'VN', + name: 'Vietnam', + dialCode: '+84', + ), + const Country( + isoCode: 'VG', + name: 'Virgin Islands (British)', + dialCode: '+1284', + ), + const Country( + isoCode: 'VI', + name: 'Virgin Islands (U.S.)', + dialCode: '+1340', + ), + const Country( + isoCode: 'WF', + name: 'Wallis and Futuna', + dialCode: '+681', + ), + const Country( + isoCode: 'YE', + name: 'Yemen', + dialCode: '+967', + ), + const Country( + isoCode: 'ZM', + name: 'Zambia', + dialCode: '+260', + ), + const Country( + isoCode: 'ZW', + name: 'Zimbabwe', + dialCode: '+263', + ), + ]; +} diff --git a/lib/src/components/phone_input/countries_dialog.dart b/lib/src/components/phone_input/countries_dialog.dart new file mode 100644 index 00000000..92919ad9 --- /dev/null +++ b/lib/src/components/phone_input/countries_dialog.dart @@ -0,0 +1,123 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import '../../../zeta_flutter.dart'; + +/// Class for [CountriesDialog] +class CountriesDialog extends StatefulWidget { + ///Constructor of [CountriesDialog] + const CountriesDialog({ + super.key, + this.zeta, + required this.button, + required this.items, + required this.onChanged, + this.enabled = true, + this.useRootNavigator = true, + }); + + /// Sometimes it is needed to pass an instance of [Zeta] from outside. + final Zeta? zeta; + + /// The button, which opens the dialog. + final Widget button; + + /// List of [DropdownMenuItem] + final List> items; + + /// Called when an item is selected. + final ValueSetter onChanged; + + /// Determines if the button should be enabled (default) or disabled. + final bool enabled; + + /// Determines if the root navigator should be used. + final bool useRootNavigator; + + @override + State> createState() => _CountriesDialogState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(IterableProperty>('items', items)) + ..add(ObjectFlagProperty>.has('onChanged', onChanged)) + ..add(DiagnosticsProperty('enabled', enabled)) + ..add(DiagnosticsProperty('useRootNavigator', useRootNavigator)); + } +} + +class _CountriesDialogState extends State> { + Future _showCountriesDialog( + BuildContext context, { + Zeta? zeta, + required List> items, + bool barrierDismissible = true, + bool useRootNavigator = true, + }) => + showDialog( + context: context, + barrierDismissible: barrierDismissible, + useRootNavigator: useRootNavigator, + builder: (_) => _CountriesList( + items: items, + zeta: zeta, + ), + ); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: widget.items.isEmpty || !widget.enabled + ? null + : () async { + final item = await _showCountriesDialog( + context, + zeta: widget.zeta, + items: widget.items, + useRootNavigator: widget.useRootNavigator, + ); + widget.onChanged(item); + }, + child: widget.button, + ); + } +} + +class _CountriesList extends StatelessWidget { + const _CountriesList({ + required this.items, + this.zeta, + }); + + final Zeta? zeta; + final List> items; + + @override + Widget build(BuildContext context) { + final zeta = this.zeta ?? Zeta.of(context); + + return AlertDialog( + surfaceTintColor: zeta.colors.surfacePrimary, + shape: const RoundedRectangleBorder(borderRadius: ZetaRadius.large), + content: SizedBox( + width: double.maxFinite, + child: ListView.builder( + shrinkWrap: true, + itemCount: items.length, + itemBuilder: (_, index) => InkWell( + onTap: () { + Navigator.of(context).pop(items[index].value); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: ZetaSpacing.xs, + ), + child: items[index].child, + ), + ), + ), + ), + ); + } +} diff --git a/lib/src/components/phone_input/phone_input.dart b/lib/src/components/phone_input/phone_input.dart new file mode 100644 index 00000000..58e80f2f --- /dev/null +++ b/lib/src/components/phone_input/phone_input.dart @@ -0,0 +1,349 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import '../../../zeta_flutter.dart'; +import 'countries.dart'; +import 'countries_dialog.dart'; + +/// ZetaPhoneInput allows entering phone numbers. +class ZetaPhoneInput extends StatefulWidget { + /// Constructor for [ZetaPhoneInput]. + const ZetaPhoneInput({ + super.key, + this.label, + this.hint, + this.enabled = true, + this.rounded = true, + this.hasError = false, + this.errorText, + this.onChanged, + this.countryDialCode, + this.phoneNumber, + this.countries, + }); + + /// If provided, displays a label above the input field. + final String? label; + + /// If provided, displays a hint below the input field. + final String? hint; + + /// Determines if the inputs should be enabled (default) or disabled. + final bool enabled; + + /// Determines if the input field corners are rounded (default) or sharp. + final bool rounded; + + /// Determines if the input field should be displayed in error style. + /// Default is `false`. + /// If `enabled` is `false`, this has no effect. + final bool hasError; + + /// In combination with `hasError: true`, provides the error message + /// to be displayed below the input field. + final String? errorText; + + /// A callback, which provides the entered phone number. + final void Function(Map?)? onChanged; + + /// The initial value for the country dial code including leading + + final String? countryDialCode; + + /// The initial value for the phone number + final String? phoneNumber; + + /// List of countries ISO 3166-1 alpha-2 codes + final List? countries; + + @override + State createState() => _ZetaPhoneInputState(); + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(StringProperty('label', label)) + ..add(StringProperty('hint', hint)) + ..add(DiagnosticsProperty('enabled', enabled)) + ..add(DiagnosticsProperty('rounded', rounded)) + ..add(DiagnosticsProperty('hasError', hasError)) + ..add(StringProperty('errorText', errorText)) + ..add(ObjectFlagProperty? p1)?>.has('onChanged', onChanged)) + ..add(StringProperty('countryDialCode', countryDialCode)) + ..add(StringProperty('phoneNumber', phoneNumber)) + ..add(IterableProperty('countries', countries)); + } +} + +class _ZetaPhoneInputState extends State { + bool _hasError = false; + late List _countries; + late Country _selectedCountry; + late String _phoneNumber; + + @override + void initState() { + super.initState(); + _countries = widget.countries?.isEmpty ?? true + ? Countries.list + : Countries.list.where((country) => widget.countries!.contains(country.isoCode)).toList(); + if (_countries.isNotEmpty && (widget.countries?.isNotEmpty ?? false)) { + _countries.sort( + (a, b) => widget.countries!.indexOf(a.isoCode).compareTo( + widget.countries!.indexOf(b.isoCode), + ), + ); + } + if (_countries.isEmpty) _countries = Countries.list; + _selectedCountry = _countries.firstWhereOrNull( + (country) => country.dialCode == widget.countryDialCode, + ) ?? + _countries.first; + _phoneNumber = widget.phoneNumber ?? ''; + _hasError = widget.hasError; + } + + @override + void didUpdateWidget(ZetaPhoneInput oldWidget) { + super.didUpdateWidget(oldWidget); + _hasError = widget.hasError; + } + + void _onChanged({Country? selectedCountry, String? phoneNumber}) { + setState(() { + if (selectedCountry != null) _selectedCountry = selectedCountry; + if (phoneNumber != null) _phoneNumber = phoneNumber; + }); + widget.onChanged?.call( + _phoneNumber.isEmpty + ? {} + : { + 'countryDialCode': _selectedCountry.dialCode, + 'phoneNumber': _phoneNumber, + }, + ); + } + + @override + Widget build(BuildContext context) { + final zeta = Zeta.of(context); + final showError = _hasError && widget.errorText != null; + final hintErrorColor = widget.enabled + ? showError + ? zeta.colors.red + : zeta.colors.cool.shade70 + : zeta.colors.cool.shade50; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (widget.label != null) + Padding( + padding: const EdgeInsets.only(bottom: 5), + child: Text( + widget.label!, + style: ZetaTextStyles.bodyMedium.copyWith( + color: widget.enabled ? zeta.colors.textDefault : zeta.colors.cool.shade50, + ), + ), + ), + SizedBox( + width: double.infinity, + child: Row( + children: [ + SizedBox( + width: 64, + height: 48, + child: DecoratedBox( + decoration: BoxDecoration( + color: widget.enabled ? zeta.colors.surfacePrimary : zeta.colors.cool.shade30, + borderRadius: widget.rounded + ? const BorderRadius.only( + topLeft: Radius.circular(ZetaSpacing.xxs), + bottomLeft: Radius.circular(ZetaSpacing.xxs), + ) + : ZetaRadius.none, + border: Border( + top: BorderSide(color: zeta.colors.cool.shade40), + bottom: BorderSide(color: zeta.colors.cool.shade40), + left: BorderSide(color: zeta.colors.cool.shade40), + ), + ), + child: CountriesDialog( + zeta: zeta, + enabled: widget.enabled, + button: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only( + left: ZetaSpacing.x2_5, + ), + child: Image.asset( + _selectedCountry.flagUri, + package: 'zeta_flutter', + width: 26, + height: 18, + fit: BoxFit.fitHeight, + ), + ), + Icon( + widget.rounded ? ZetaIcons.expand_more_round : ZetaIcons.expand_more_sharp, + color: widget.enabled ? zeta.colors.textDefault : zeta.colors.cool.shade50, + size: ZetaSpacing.x5, + ), + ], + ), + items: _countries + .map( + (country) => DropdownMenuItem( + value: country, + child: Row( + children: [ + SizedBox( + width: 60, + child: Text(country.dialCode), + ), + Expanded( + child: Text(country.name), + ), + ], + ), + ), + ) + .toList(), + onChanged: (value) => _onChanged(selectedCountry: value), + ), + ), + ), + Expanded( + child: TextFormField( + maxLength: 20, + initialValue: widget.phoneNumber, + enabled: widget.enabled, + inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[\d\s\-]'))], + keyboardType: TextInputType.phone, + onChanged: (value) => _onChanged(phoneNumber: value), + style: ZetaTextStyles.bodyMedium.copyWith( + color: widget.enabled ? zeta.colors.textDefault : zeta.colors.cool.shade50, + ), + decoration: InputDecoration( + counterText: '', + isDense: true, + contentPadding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 10, + ), + hintStyle: ZetaTextStyles.bodyMedium.copyWith( + color: widget.enabled ? zeta.colors.textDefault : zeta.colors.cool.shade50, + ), + prefixIcon: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: ZetaSpacing.xs), + child: Text( + _selectedCountry.dialCode, + style: ZetaTextStyles.bodyMedium.copyWith( + color: widget.enabled ? zeta.colors.textDefault : zeta.colors.cool.shade50, + ), + ), + ), + ], + ), + prefixIconConstraints: const BoxConstraints( + minHeight: ZetaSpacing.x12, + minWidth: ZetaSpacing.x10, + ), + filled: true, + fillColor: widget.enabled + ? _hasError + ? zeta.colors.red.shade10 + : zeta.colors.surfacePrimary + : zeta.colors.cool.shade30, + enabledBorder: _hasError + ? _errorInputBorder(zeta, rounded: widget.rounded) + : _defaultInputBorder(zeta, rounded: widget.rounded), + focusedBorder: _hasError + ? _errorInputBorder(zeta, rounded: widget.rounded) + : _focusedInputBorder(zeta, rounded: widget.rounded), + disabledBorder: _defaultInputBorder(zeta, rounded: widget.rounded), + errorBorder: _errorInputBorder(zeta, rounded: widget.rounded), + focusedErrorBorder: _errorInputBorder(zeta, rounded: widget.rounded), + ), + ), + ), + ], + ), + ), + if (widget.hint != null || showError) + Padding( + padding: const EdgeInsets.only(top: 5), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 8), + child: Icon( + showError && widget.enabled + ? (widget.rounded ? ZetaIcons.error_round : ZetaIcons.error_sharp) + : (widget.rounded ? ZetaIcons.info_round : ZetaIcons.info_sharp), + size: ZetaSpacing.b, + color: hintErrorColor, + ), + ), + Expanded( + child: Text( + showError && widget.enabled ? widget.errorText! : widget.hint!, + style: ZetaTextStyles.bodyXSmall.copyWith( + color: hintErrorColor, + ), + ), + ), + ], + ), + ), + ], + ); + } + + OutlineInputBorder _defaultInputBorder( + Zeta zeta, { + required bool rounded, + }) => + OutlineInputBorder( + borderRadius: rounded + ? const BorderRadius.only( + topRight: Radius.circular(ZetaSpacing.xxs), + bottomRight: Radius.circular(ZetaSpacing.xxs), + ) + : ZetaRadius.none, + borderSide: BorderSide(color: zeta.colors.cool.shade40), + ); + + OutlineInputBorder _focusedInputBorder( + Zeta zeta, { + required bool rounded, + }) => + OutlineInputBorder( + borderRadius: rounded + ? const BorderRadius.only( + topRight: Radius.circular(ZetaSpacing.xxs), + bottomRight: Radius.circular(ZetaSpacing.xxs), + ) + : ZetaRadius.none, + borderSide: BorderSide(color: zeta.colors.blue.shade50), + ); + + OutlineInputBorder _errorInputBorder( + Zeta zeta, { + required bool rounded, + }) => + OutlineInputBorder( + borderRadius: rounded + ? const BorderRadius.only( + topRight: Radius.circular(ZetaSpacing.xxs), + bottomRight: Radius.circular(ZetaSpacing.xxs), + ) + : ZetaRadius.none, + borderSide: BorderSide(color: zeta.colors.red.shade50), + ); +} diff --git a/lib/src/utils/extensions.dart b/lib/src/utils/extensions.dart index 77dc6bcc..3b4d5a45 100644 --- a/lib/src/utils/extensions.dart +++ b/lib/src/utils/extensions.dart @@ -101,3 +101,14 @@ extension StringExtensions on String? { return '${this![0].toUpperCase()}${this!.substring(1).toLowerCase()}'; } } + +/// Extension [FirstWhereOrNull] on [Iterable]. +extension FirstWhereOrNull on Iterable { + /// Returns the first element satisfying test, or null if there are none. + T? firstWhereOrNull(bool Function(T element) test) { + for (final element in this) { + if (test(element)) return element; + } + return null; + } +} diff --git a/lib/zeta_flutter.dart b/lib/zeta_flutter.dart index 470ce04e..9937c38e 100644 --- a/lib/zeta_flutter.dart +++ b/lib/zeta_flutter.dart @@ -31,6 +31,7 @@ export 'src/components/list_item/list_item.dart'; export 'src/components/navigation bar/navigation_bar.dart'; export 'src/components/pagination/pagination.dart'; export 'src/components/password/password_input.dart'; +export 'src/components/phone_input/phone_input.dart'; export 'src/components/progress/progress_bar.dart'; export 'src/components/progress/progress_circle.dart'; export 'src/components/radio/radio.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 4c1527ab..9c230be8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,4 +45,6 @@ flutter: - family: zeta-icons-sharp fonts: - asset: lib/src/assets/fonts/zeta-icons-sharp.ttf + assets: + - lib/src/assets/flags/ uses-material-design: true From e3df5f14aeeed2db7aa356aa87906d77c956309c Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Tue, 16 Apr 2024 13:05:03 +0300 Subject: [PATCH 05/15] restore main.dart in example (#23) --- example/lib/main.dart | 194 ++++++++++++------------------------------ 1 file changed, 56 insertions(+), 138 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 5078d0e5..596eed2e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,151 +1,69 @@ import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:zeta_example/pages/components/accordion_example.dart'; -import 'package:zeta_example/pages/components/app_bar_example.dart'; -import 'package:zeta_example/pages/components/avatar_example.dart'; -import 'package:zeta_example/pages/components/badges_example.dart'; -import 'package:zeta_example/pages/components/banner_example.dart'; -import 'package:zeta_example/pages/components/bottom_sheet_example.dart'; -import 'package:zeta_example/pages/components/breadcrumbs_example.dart'; -import 'package:zeta_example/pages/components/button_example.dart'; -import 'package:zeta_example/pages/components/checkbox_example.dart'; -import 'package:zeta_example/pages/components/chip_example.dart'; -import 'package:zeta_example/pages/components/date_input_example.dart'; -import 'package:zeta_example/pages/components/dialog_example.dart'; -import 'package:zeta_example/pages/components/dialpad_example.dart'; -import 'package:zeta_example/pages/components/dropdown_example.dart'; -import 'package:zeta_example/pages/components/list_item_example.dart'; -import 'package:zeta_example/pages/components/navigation_bar_example.dart'; -import 'package:zeta_example/pages/components/radio_example.dart'; -import 'package:zeta_example/pages/components/stepper_example.dart'; -import 'package:zeta_example/pages/components/switch_example.dart'; -import 'package:zeta_example/pages/components/snackbar_example.dart'; -import 'package:zeta_example/pages/components/tabs_example.dart'; -import 'package:zeta_example/pages/theme/color_example.dart'; -import 'package:zeta_example/pages/components/password_input_example.dart'; -import 'package:zeta_example/pages/components/progress_example.dart'; -import 'package:zeta_example/pages/assets/icons_example.dart'; -import 'package:zeta_example/pages/theme/radius_example.dart'; -import 'package:zeta_example/pages/theme/spacing_example.dart'; -import 'package:zeta_example/pages/theme/typography_example.dart'; -import 'package:zeta_example/widgets.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:zeta_example/theme_service.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; +import 'home.dart'; -class Component { - final String name; - final WidgetBuilder pageBuilder; - final List children; - Component(this.name, this.pageBuilder, [this.children = const []]); -} - -final List components = [ - Component(AccordionExample.name, (context) => const AccordionExample()), - Component(AppBarExample.name, (context) => const AppBarExample()), - Component(AvatarExample.name, (context) => const AvatarExample()), - Component(BannerExample.name, (context) => const BannerExample()), - Component(BadgesExample.name, (context) => const BadgesExample()), - Component(BottomSheetExample.name, (context) => const BottomSheetExample()), - Component(BreadCrumbsExample.name, (context) => const BreadCrumbsExample()), - Component(ButtonExample.name, (context) => const ButtonExample()), - Component(CheckBoxExample.name, (context) => const CheckBoxExample()), - Component(ChipExample.name, (context) => const ChipExample()), - Component(ListItemExample.name, (context) => const ListItemExample()), - Component(NavigationBarExample.name, (context) => const NavigationBarExample()), - Component(PasswordInputExample.name, (context) => const PasswordInputExample()), - Component(DropdownExample.name, (context) => const DropdownExample()), - Component(ProgressExample.name, (context) => const ProgressExample()), - Component(SnackBarExample.name, (context) => const SnackBarExample()), - Component(StepperExample.name, (context) => const StepperExample()), - Component(TabsExample.name, (context) => const TabsExample()), - Component(DialPadExample.name, (context) => const DialPadExample()), - Component(RadioButtonExample.name, (context) => const RadioButtonExample()), - Component(SwitchExample.name, (context) => const SwitchExample()), - Component(DateInputExample.name, (context) => const DateInputExample()), - Component(DialogExample.name, (context) => const DialogExample()), -]; - -final List theme = [ - Component(ColorExample.name, (context) => const ColorExample()), - Component(TypographyExample.name, (context) => const TypographyExample()), - Component(RadiusExample.name, (context) => const RadiusExample()), - Component(SpacingExample.name, (context) => const SpacingExample()), -]; -final List assets = [ - Component(IconsExample.name, (context) => const IconsExample()), -]; +void main() async { + WidgetsFlutterBinding.ensureInitialized(); -class Home extends StatefulWidget { - const Home({super.key}); + final preferences = await SharedPreferences.getInstance(); + final themeService = SharedPrefsThemeService(preferences); + final themePreferences = await themeService.loadTheme(); - @override - State createState() => _HomeState(); + runApp( + ZetaExample( + themeService: themeService, + initialThemeData: themePreferences.$1 ?? ZetaThemeData(), + initialThemeMode: themePreferences.$2 ?? ThemeMode.system, + initialContrast: themePreferences.$3 ?? ZetaContrast.aa, + ), + ); } -final GoRouter router = GoRouter( - routes: [ - GoRoute( - path: '/', - name: 'Home', - builder: (_, __) => const Home(), - routes: [ - ...[ - ...components, - ...assets, - ...theme, - ].map( - (e) => GoRoute( - path: e.name, - name: e.name, - builder: (_, __) => e.pageBuilder.call(_), - routes: e.children - .map((f) => GoRoute( - path: f.name, - name: f.name, - builder: (_, __) => f.pageBuilder(_), - )) - .toList(), - ), - ), - ], - ), - ], -); +class ZetaExample extends StatelessWidget { + const ZetaExample({ + super.key, + required this.themeService, + required this.initialContrast, + required this.initialThemeMode, + required this.initialThemeData, + }); + + final ZetaThemeService themeService; + final ZetaContrast initialContrast; + final ThemeMode initialThemeMode; + final ZetaThemeData initialThemeData; -class _HomeState extends State { @override Widget build(BuildContext context) { - final _components = components..sort((a, b) => a.name.compareTo(b.name)); - final _assets = assets..sort((a, b) => a.name.compareTo(b.name)); - final _theme = theme..sort((a, b) => a.name.compareTo(b.name)); - return ExampleScaffold( - name: 'Zeta', - child: SingleChildScrollView( - child: Column( - children: [ - ExpansionTile( - title: Text('Widgets'), - backgroundColor: Zeta.of(context).colors.warm.shade30, - children: _components - .map((item) => ListTile(title: Text(item.name), onTap: () => context.go('/${item.name}'))) - .toList(), - ), - ExpansionTile( - title: Text('Theme'), - backgroundColor: Zeta.of(context).colors.warm.shade30, - children: _theme - .map((item) => ListTile(title: Text(item.name), onTap: () => context.go('/${item.name}'))) - .toList(), - ), - ExpansionTile( - title: Text('Assets'), - backgroundColor: Zeta.of(context).colors.warm.shade30, - children: _assets - .map((item) => ListTile(title: Text(item.name), onTap: () => context.go('/${item.name}'))) - .toList(), - ), - ], - ), - ), + return ZetaProvider( + themeService: themeService, + initialContrast: initialContrast, + initialThemeData: initialThemeData, + initialThemeMode: initialThemeMode, + builder: (context, themeData, themeMode) { + final dark = themeData.colorsDark.toScheme(); + final light = themeData.colorsLight.toScheme(); + return MaterialApp.router( + routerConfig: router, + themeMode: themeMode, + theme: ThemeData( + useMaterial3: true, + fontFamily: themeData.fontFamily, + scaffoldBackgroundColor: light.background, + colorScheme: light, + textTheme: zetaTextTheme, + ), + darkTheme: ThemeData( + useMaterial3: true, + fontFamily: themeData.fontFamily, + scaffoldBackgroundColor: dark.background, + colorScheme: dark, + textTheme: zetaTextTheme, + ), + ); + }, ); } } From e421095f1a51c250deaa3f1a73aed611944d0496 Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Tue, 16 Apr 2024 13:15:37 +0300 Subject: [PATCH 06/15] Component phone input (#24) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * ZetaPhoneInput initial commit * complete ZetaPhoneInput; add flags * create phoneInputUseCase in Widgetbook * refactor phone input to use native alert dialog * don't use root navigator in widgetbook --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> --- .../pages/components/phone_input_widgetbook.dart | 1 + lib/src/components/phone_input/phone_input.dart | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/example/widgetbook/pages/components/phone_input_widgetbook.dart b/example/widgetbook/pages/components/phone_input_widgetbook.dart index c63f423f..1b36f6c0 100644 --- a/example/widgetbook/pages/components/phone_input_widgetbook.dart +++ b/example/widgetbook/pages/components/phone_input_widgetbook.dart @@ -22,6 +22,7 @@ Widget phoneInputUseCase(BuildContext context) { label: 'Phone number', hint: 'Enter your phone number', countries: countries.isEmpty ? null : countries.toUpperCase().split(','), + useRootNavigator: false, ), ); }, diff --git a/lib/src/components/phone_input/phone_input.dart b/lib/src/components/phone_input/phone_input.dart index 58e80f2f..0ac45469 100644 --- a/lib/src/components/phone_input/phone_input.dart +++ b/lib/src/components/phone_input/phone_input.dart @@ -20,6 +20,7 @@ class ZetaPhoneInput extends StatefulWidget { this.countryDialCode, this.phoneNumber, this.countries, + this.useRootNavigator = true, }); /// If provided, displays a label above the input field. @@ -55,6 +56,9 @@ class ZetaPhoneInput extends StatefulWidget { /// List of countries ISO 3166-1 alpha-2 codes final List? countries; + /// Determines if the root navigator should be used in the [CountriesDialog]. + final bool useRootNavigator; + @override State createState() => _ZetaPhoneInputState(); @override @@ -70,7 +74,8 @@ class ZetaPhoneInput extends StatefulWidget { ..add(ObjectFlagProperty? p1)?>.has('onChanged', onChanged)) ..add(StringProperty('countryDialCode', countryDialCode)) ..add(StringProperty('phoneNumber', phoneNumber)) - ..add(IterableProperty('countries', countries)); + ..add(IterableProperty('countries', countries)) + ..add(DiagnosticsProperty('useRootNavigator', useRootNavigator)); } } From 8270f31ad35dbc86558c3e27473ddd3832352c72 Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Tue, 16 Apr 2024 13:56:08 +0300 Subject: [PATCH 07/15] Component phone input (#25) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * ZetaPhoneInput initial commit * complete ZetaPhoneInput; add flags * create phoneInputUseCase in Widgetbook * refactor phone input to use native alert dialog * don't use root navigator in widgetbook * pass parameter useRootNavigator * restore some missing countries in the list --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> --- lib/src/components/phone_input/countries.dart | 27 ++++++++++++++++++- .../components/phone_input/phone_input.dart | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/src/components/phone_input/countries.dart b/lib/src/components/phone_input/countries.dart index 12076629..0e600934 100644 --- a/lib/src/components/phone_input/countries.dart +++ b/lib/src/components/phone_input/countries.dart @@ -177,6 +177,11 @@ class Countries { name: 'Botswana', dialCode: '+267', ), + const Country( + isoCode: 'BV', + name: 'Bouvet Island', + dialCode: '+47', + ), const Country( isoCode: 'BR', name: 'Brazil', @@ -472,6 +477,11 @@ class Countries { name: 'Guatemala', dialCode: '+502', ), + const Country( + isoCode: 'GG', + name: 'Guernsey', + dialCode: '+44', + ), const Country( isoCode: 'GN', name: 'Guinea', @@ -547,6 +557,11 @@ class Countries { name: 'Ireland', dialCode: '+353', ), + const Country( + isoCode: 'IM', + name: 'Isle of Man', + dialCode: '+44', + ), const Country( isoCode: 'IL', name: 'Israel', @@ -567,6 +582,11 @@ class Countries { name: 'Japan', dialCode: '+81', ), + const Country( + isoCode: 'JE', + name: 'Jersey', + dialCode: '+44', + ), const Country( isoCode: 'JO', name: 'Jordan', @@ -1062,6 +1082,11 @@ class Countries { name: 'Suriname', dialCode: '+597', ), + const Country( + isoCode: 'SJ', + name: 'Svalbard and Jan Mayen', + dialCode: '+47', + ), const Country( isoCode: 'SZ', name: 'Swaziland', @@ -1169,7 +1194,7 @@ class Countries { ), const Country( isoCode: 'GB', - name: 'Great Britain and Northern Ireland', + name: 'United Kingdom of Great Britain and Northern Ireland', dialCode: '+44', ), const Country( diff --git a/lib/src/components/phone_input/phone_input.dart b/lib/src/components/phone_input/phone_input.dart index 0ac45469..e853e99a 100644 --- a/lib/src/components/phone_input/phone_input.dart +++ b/lib/src/components/phone_input/phone_input.dart @@ -175,6 +175,7 @@ class _ZetaPhoneInputState extends State { ), child: CountriesDialog( zeta: zeta, + useRootNavigator: widget.useRootNavigator, enabled: widget.enabled, button: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, From a5fc795ab4dab36a646b73e1b29583f0bacd5a87 Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:11:19 +0300 Subject: [PATCH 08/15] Navigation rail (#27) * create NavigationRail * restore main.dart in example * navigation rail example * create widgetbook * add SafeArea; rename parameter wordWrap * add MouseRegion & SelectionContainer.disabled --- example/lib/home.dart | 2 + .../components/navigation_rail_example.dart | 77 ++++++ example/widgetbook/main.dart | 2 + .../navigation_rail_widgetbook.dart | 65 +++++ .../navigation_rail/navigation_rail.dart | 229 ++++++++++++++++++ lib/zeta_flutter.dart | 1 + 6 files changed, 376 insertions(+) create mode 100644 example/lib/pages/components/navigation_rail_example.dart create mode 100644 example/widgetbook/pages/components/navigation_rail_widgetbook.dart create mode 100644 lib/src/components/navigation_rail/navigation_rail.dart diff --git a/example/lib/home.dart b/example/lib/home.dart index 345ee042..a49b8d60 100644 --- a/example/lib/home.dart +++ b/example/lib/home.dart @@ -15,6 +15,7 @@ import 'package:zeta_example/pages/components/dialpad_example.dart'; import 'package:zeta_example/pages/components/dropdown_example.dart'; import 'package:zeta_example/pages/components/list_item_example.dart'; import 'package:zeta_example/pages/components/navigation_bar_example.dart'; +import 'package:zeta_example/pages/components/navigation_rail_example.dart'; import 'package:zeta_example/pages/components/phone_input_example.dart'; import 'package:zeta_example/pages/components/radio_example.dart'; import 'package:zeta_example/pages/components/stepper_example.dart'; @@ -64,6 +65,7 @@ final List components = [ Component(DateInputExample.name, (context) => const DateInputExample()), Component(PhoneInputExample.name, (context) => const PhoneInputExample()), Component(DialogExample.name, (context) => const DialogExample()), + Component(NavigationRailExample.name, (context) => const NavigationRailExample()), ]; final List theme = [ diff --git a/example/lib/pages/components/navigation_rail_example.dart b/example/lib/pages/components/navigation_rail_example.dart new file mode 100644 index 00000000..5b930512 --- /dev/null +++ b/example/lib/pages/components/navigation_rail_example.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; +import 'package:zeta_example/widgets.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +class NavigationRailExample extends StatefulWidget { + static const String name = 'NavigationRail'; + + const NavigationRailExample({Key? key}) : super(key: key); + + @override + State createState() => _NavigationRailExampleState(); +} + +class _NavigationRailExampleState extends State { + List _titles = [ + 'Label', + 'User Preferences', + 'Account Settings', + 'Label', + ]; + int? _selectedIndex; + + @override + Widget build(BuildContext context) { + final zeta = Zeta.of(context); + + return SafeArea( + child: ExampleScaffold( + name: 'Navigation Rail', + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ZetaNavigationRail( + selectedIndex: _selectedIndex, + onSelect: (index) => setState(() => _selectedIndex = index), + wordWrap: false, + items: [ + ZetaNavigationRailItem( + label: 'Label', + icon: Icon(ZetaIcons.star_round), + ), + ZetaNavigationRailItem( + label: 'User\nPreferences', + icon: Icon(ZetaIcons.star_round), + ), + ZetaNavigationRailItem( + label: 'Account Settings', + icon: Icon(ZetaIcons.star_round), + ), + ZetaNavigationRailItem( + label: 'Label', + icon: Icon(ZetaIcons.star_round), + disabled: true, + ), + ], + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(ZetaSpacing.x5), + child: _selectedIndex == null + ? const SizedBox() + : Text( + _titles[_selectedIndex!], + textAlign: TextAlign.center, + style: ZetaTextStyles.titleMedium.copyWith( + color: zeta.colors.textDefault, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/example/widgetbook/main.dart b/example/widgetbook/main.dart index 6911d1a3..eed19b5b 100644 --- a/example/widgetbook/main.dart +++ b/example/widgetbook/main.dart @@ -20,6 +20,7 @@ import 'pages/components/dropdown_widgetbook.dart'; import 'pages/components/in_page_banner_widgetbook.dart'; import 'pages/components/list_item_widgetbook.dart'; import 'pages/components/navigation_bar_widgetbook.dart'; +import 'pages/components/navigation_rail_widgetbook.dart'; import 'pages/components/pagination_widgetbook.dart'; import 'pages/components/password_input_widgetbook.dart'; import 'pages/components/phone_input_widgetbook.dart'; @@ -126,6 +127,7 @@ class HotReload extends StatelessWidget { builder: (context) => stepperUseCase(context), ), WidgetbookUseCase(name: 'Dialog', builder: (context) => dialogUseCase(context)), + WidgetbookUseCase(name: 'Navigation Rail', builder: (context) => navigationRailUseCase(context)), ]..sort((a, b) => a.name.compareTo(b.name)), ), WidgetbookCategory( diff --git a/example/widgetbook/pages/components/navigation_rail_widgetbook.dart b/example/widgetbook/pages/components/navigation_rail_widgetbook.dart new file mode 100644 index 00000000..f981bfd7 --- /dev/null +++ b/example/widgetbook/pages/components/navigation_rail_widgetbook.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +import '../../test/test_components.dart'; +import '../../utils/utils.dart'; + +Widget navigationRailUseCase(BuildContext context) { + final zeta = Zeta.of(context); + int? selectedIndex; + final items = context.knobs.string( + label: 'Items separated with comma', + initialValue: 'Label,User Preferences,Account Settings,Label', + ); + final rounded = context.knobs.boolean(label: 'Rounded', initialValue: true); + final iconData = iconKnob( + context, + name: "Icon", + rounded: rounded, + initial: rounded ? ZetaIcons.star_round : ZetaIcons.star_sharp, + ); + final wordWrap = context.knobs.boolean(label: 'Word wrap', initialValue: true); + final disabled = context.knobs.boolean(label: 'Disabled', initialValue: false); + final itemsList = items.split(',').where((element) => element.trim().isNotEmpty).toList(); + return SafeArea( + child: WidgetbookTestWidget( + widget: StatefulBuilder( + builder: (context, setState) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ZetaNavigationRail( + selectedIndex: selectedIndex, + onSelect: (index) => setState(() => selectedIndex = index), + wordWrap: wordWrap, + items: itemsList + .map((item) => ZetaNavigationRailItem( + label: item, + icon: Icon(iconData), + disabled: disabled, + )) + .toList(), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(ZetaSpacing.x5), + child: selectedIndex == null + ? const SizedBox() + : Text( + itemsList[selectedIndex!], + textAlign: TextAlign.center, + style: ZetaTextStyles.titleMedium.copyWith( + color: zeta.colors.textDefault, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ); + }, + ), + ), + ); +} diff --git a/lib/src/components/navigation_rail/navigation_rail.dart b/lib/src/components/navigation_rail/navigation_rail.dart new file mode 100644 index 00000000..1fbfc4dc --- /dev/null +++ b/lib/src/components/navigation_rail/navigation_rail.dart @@ -0,0 +1,229 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import '../../../zeta_flutter.dart'; + +/// [ZetaNavigationRail] +class ZetaNavigationRail extends StatefulWidget { + /// Constructor for [ZetaNavigationRail]. + const ZetaNavigationRail({ + super.key, + required this.items, + this.selectedIndex, + this.onSelect, + this.rounded = true, + this.margin = const EdgeInsets.all(ZetaSpacing.x5), + this.itemSpacing = const EdgeInsets.only(bottom: ZetaSpacing.xxs), + this.itemPadding, + this.wordWrap, + }); + + /// Required list of navigation items. + final List items; + + /// Initially selected item form the list of `items`. + final int? selectedIndex; + + /// Called when an item is selected. + final void Function(int)? onSelect; + + /// Determines if the items are rounded (default) or sharp. + final bool rounded; + + /// The margin around the [ZetaNavigationRail]. + /// Default is: + /// ``` + /// const EdgeInsets.all(ZetaSpacing.x5) + /// ``` + final EdgeInsets margin; + + /// The spacing between items in [ZetaNavigationRail]. + /// Default is: + /// ``` + /// const EdgeInsets.only(bottom: ZetaSpacing.xxs) + /// ``` + final EdgeInsets itemSpacing; + + /// The padding within an item in [ZetaNavigationRail]. + /// Default is: + /// ``` + /// const EdgeInsets.symmetric( + /// horizontal: ZetaSpacing.xs, + /// vertical: ZetaSpacing.s, + /// ), + /// ``` + final EdgeInsets? itemPadding; + + /// Determines if words in items' labels should be wrapped on separate lines. + /// Default is `true`. + final bool? wordWrap; + + @override + State createState() => _ZetaNavigationRailState(); + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('rounded', rounded)) + ..add(IntProperty('selectedIndex', selectedIndex)) + ..add(ObjectFlagProperty.has('onSelect', onSelect)) + ..add(IterableProperty('items', items)) + ..add(DiagnosticsProperty('margin', margin)) + ..add(DiagnosticsProperty('itemSpacing', itemSpacing)) + ..add(DiagnosticsProperty('itemPadding', itemPadding)) + ..add(DiagnosticsProperty('wordWrap', wordWrap)); + } +} + +class _ZetaNavigationRailState extends State { + @override + Widget build(BuildContext context) { + return Padding( + padding: widget.margin, + child: IntrinsicWidth( + child: Column( + children: [ + for (int i = 0; i < widget.items.length; i++) + Row( + children: [ + Expanded( + child: Padding( + padding: widget.itemSpacing, + child: _ZetaNavigationRailItemContent( + label: widget.items[i].label, + icon: widget.items[i].icon, + selected: widget.selectedIndex == i, + disabled: widget.items[i].disabled, + onTap: () => widget.onSelect?.call(i), + rounded: widget.rounded, + padding: widget.itemPadding, + wordWrap: widget.wordWrap, + ), + ), + ), + ], + ), + ], + ), + ), + ); + } +} + +class _ZetaNavigationRailItemContent extends StatelessWidget { + const _ZetaNavigationRailItemContent({ + required this.label, + this.icon, + this.selected = false, + this.disabled = false, + this.onTap, + this.rounded = true, + this.padding, + this.wordWrap, + }); + + final String label; + final Widget? icon; + final bool selected; + final bool disabled; + final VoidCallback? onTap; + final bool rounded; + final EdgeInsets? padding; + final bool? wordWrap; + + @override + Widget build(BuildContext context) { + final zeta = Zeta.of(context); + return MouseRegion( + child: GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: disabled ? null : onTap, + child: DecoratedBox( + decoration: BoxDecoration( + color: disabled + ? null + : selected + ? zeta.colors.blue.shade10 + : null, + borderRadius: rounded ? ZetaRadius.rounded : null, + ), + child: ConstrainedBox( + constraints: const BoxConstraints( + minWidth: ZetaSpacing.x16, + minHeight: ZetaSpacing.x16, + ), + child: SelectionContainer.disabled( + child: Padding( + padding: padding ?? + const EdgeInsets.symmetric( + horizontal: ZetaSpacing.xs, + vertical: ZetaSpacing.s, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (icon != null) + IconTheme( + data: IconThemeData( + color: disabled + ? zeta.colors.cool.shade50 + : selected + ? zeta.colors.textDefault + : zeta.colors.cool.shade70, + size: 24, + ), + child: icon!, + ), + Text( + (wordWrap ?? true) ? label.replaceAll(' ', '\n') : label, + textAlign: TextAlign.center, + style: ZetaTextStyles.titleSmall.copyWith( + color: disabled + ? zeta.colors.cool.shade50 + : selected + ? zeta.colors.textDefault + : zeta.colors.cool.shade70, + ), + ), + ], + ), + ), + ), + ), + ), + ), + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(ObjectFlagProperty.has('onTap', onTap)) + ..add(DiagnosticsProperty('rounded', rounded)) + ..add(DiagnosticsProperty('disabled', disabled)) + ..add(DiagnosticsProperty('selected', selected)) + ..add(DiagnosticsProperty('padding', padding)) + ..add(StringProperty('label', label)) + ..add(DiagnosticsProperty('wordWrap', wordWrap)); + } +} + +/// [ZetaNavigationRailItem] +class ZetaNavigationRailItem { + /// Constructor for [ZetaNavigationRailItem]. + const ZetaNavigationRailItem({ + required this.label, + this.icon, + this.disabled = false, + }); + + /// Item's label. + final String label; + + /// Optional item's icon. + final Widget? icon; + + /// Indicates that this navigation item is inaccessible. + final bool disabled; +} diff --git a/lib/zeta_flutter.dart b/lib/zeta_flutter.dart index 9937c38e..9181ca42 100644 --- a/lib/zeta_flutter.dart +++ b/lib/zeta_flutter.dart @@ -29,6 +29,7 @@ export 'src/components/dialog/dialog.dart'; export 'src/components/dropdown/dropdown.dart'; export 'src/components/list_item/list_item.dart'; export 'src/components/navigation bar/navigation_bar.dart'; +export 'src/components/navigation_rail/navigation_rail.dart'; export 'src/components/pagination/pagination.dart'; export 'src/components/password/password_input.dart'; export 'src/components/phone_input/phone_input.dart'; From 278321275d56324adba6db105e7e8350a2468a07 Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:45:42 +0300 Subject: [PATCH 09/15] Component tooltip (#31) * create tooltip * create Widgetbook for ZetaTooltip * add LayoutBuilder * [automated commit] lint format and import sort --------- Co-authored-by: github-actions --- example/lib/home.dart | 2 + .../lib/pages/components/tooltip_example.dart | 71 ++++++ example/widgetbook/main.dart | 2 + .../pages/components/tooltip_widgetbook.dart | 32 +++ lib/src/components/tooltip/tooltip.dart | 212 ++++++++++++++++++ lib/zeta_flutter.dart | 1 + 6 files changed, 320 insertions(+) create mode 100644 example/lib/pages/components/tooltip_example.dart create mode 100644 example/widgetbook/pages/components/tooltip_widgetbook.dart create mode 100644 lib/src/components/tooltip/tooltip.dart diff --git a/example/lib/home.dart b/example/lib/home.dart index a49b8d60..de428915 100644 --- a/example/lib/home.dart +++ b/example/lib/home.dart @@ -23,6 +23,7 @@ import 'package:zeta_example/pages/components/switch_example.dart'; import 'package:zeta_example/pages/components/snackbar_example.dart'; import 'package:zeta_example/pages/components/tabs_example.dart'; import 'package:zeta_example/pages/components/pagination_example.dart'; +import 'package:zeta_example/pages/components/tooltip_example.dart'; import 'package:zeta_example/pages/theme/color_example.dart'; import 'package:zeta_example/pages/components/password_input_example.dart'; import 'package:zeta_example/pages/components/progress_example.dart'; @@ -65,6 +66,7 @@ final List components = [ Component(DateInputExample.name, (context) => const DateInputExample()), Component(PhoneInputExample.name, (context) => const PhoneInputExample()), Component(DialogExample.name, (context) => const DialogExample()), + Component(TooltipExample.name, (context) => const TooltipExample()), Component(NavigationRailExample.name, (context) => const NavigationRailExample()), ]; diff --git a/example/lib/pages/components/tooltip_example.dart b/example/lib/pages/components/tooltip_example.dart new file mode 100644 index 00000000..01912cfc --- /dev/null +++ b/example/lib/pages/components/tooltip_example.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:zeta_example/widgets.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +class TooltipExample extends StatelessWidget { + static const String name = 'Tooltip'; + + const TooltipExample({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return ExampleScaffold( + name: 'Tooltip', + child: SizedBox( + width: double.infinity, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text('Rounded'), + const SizedBox(height: ZetaSpacing.l), + ZetaTooltip( + child: Text('Label'), + ), + const SizedBox(height: ZetaSpacing.l), + ZetaTooltip( + child: Text('Label'), + arrowDirection: ZetaTooltipArrowDirection.right, + ), + const SizedBox(height: ZetaSpacing.l), + ZetaTooltip( + child: Text('Label'), + arrowDirection: ZetaTooltipArrowDirection.up, + ), + const SizedBox(height: ZetaSpacing.l), + ZetaTooltip( + child: Text('Label'), + arrowDirection: ZetaTooltipArrowDirection.left, + ), + Divider(height: ZetaSpacing.xxl), + Text('Sharp'), + const SizedBox(height: ZetaSpacing.l), + ZetaTooltip( + child: Text('Label'), + rounded: false, + ), + const SizedBox(height: ZetaSpacing.l), + ZetaTooltip( + child: Text('Label'), + arrowDirection: ZetaTooltipArrowDirection.right, + rounded: false, + ), + const SizedBox(height: ZetaSpacing.l), + ZetaTooltip( + child: Text('Label'), + arrowDirection: ZetaTooltipArrowDirection.up, + rounded: false, + ), + const SizedBox(height: ZetaSpacing.l), + ZetaTooltip( + child: Text('Label'), + arrowDirection: ZetaTooltipArrowDirection.left, + rounded: false, + ), + ], + ), + ), + ); + } +} diff --git a/example/widgetbook/main.dart b/example/widgetbook/main.dart index eed19b5b..f5975bb9 100644 --- a/example/widgetbook/main.dart +++ b/example/widgetbook/main.dart @@ -30,6 +30,7 @@ import 'pages/components/stepper_widgetbook.dart'; import 'pages/components/switch_widgetbook.dart'; import 'pages/components/snack_bar_widgetbook.dart'; import 'pages/components/tabs_widgetbook.dart'; +import 'pages/components/tooltip_widgetbook.dart'; import 'pages/theme/color_widgetbook.dart'; import 'pages/theme/radius_widgetbook.dart'; import 'pages/theme/spacing_widgetbook.dart'; @@ -128,6 +129,7 @@ class HotReload extends StatelessWidget { ), WidgetbookUseCase(name: 'Dialog', builder: (context) => dialogUseCase(context)), WidgetbookUseCase(name: 'Navigation Rail', builder: (context) => navigationRailUseCase(context)), + WidgetbookUseCase(name: 'Tooltip', builder: (context) => tooltipUseCase(context)), ]..sort((a, b) => a.name.compareTo(b.name)), ), WidgetbookCategory( diff --git a/example/widgetbook/pages/components/tooltip_widgetbook.dart b/example/widgetbook/pages/components/tooltip_widgetbook.dart new file mode 100644 index 00000000..8212303e --- /dev/null +++ b/example/widgetbook/pages/components/tooltip_widgetbook.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +import '../../test/test_components.dart'; + +Widget tooltipUseCase(BuildContext context) { + final text = context.knobs.string( + label: 'Tooltip text', + initialValue: 'Label', + ); + final direction = context.knobs.list( + label: 'Arrow direction', + options: ZetaTooltipArrowDirection.values, + labelBuilder: (direction) => direction.name, + ); + final rounded = context.knobs.boolean(label: 'Rounded', initialValue: true); + return WidgetbookTestWidget( + widget: StatefulBuilder( + builder: (context, setState) { + return Padding( + padding: const EdgeInsets.all(ZetaSpacing.l), + child: ZetaTooltip( + child: Text(text), + rounded: rounded, + arrowDirection: direction, + ), + ); + }, + ), + ); +} diff --git a/lib/src/components/tooltip/tooltip.dart b/lib/src/components/tooltip/tooltip.dart new file mode 100644 index 00000000..b98eb2c9 --- /dev/null +++ b/lib/src/components/tooltip/tooltip.dart @@ -0,0 +1,212 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; + +import '../../../zeta_flutter.dart'; + +/// The direction of [ZetaTooltip]'s arrow +enum ZetaTooltipArrowDirection { + /// [up] + up, + + /// [down] + down, + + /// [left] + left, + + /// [right] + right, +} + +/// [ZetaTooltip] +class ZetaTooltip extends StatelessWidget { + /// Constructor for [ZetaTooltip]. + const ZetaTooltip({ + super.key, + required this.child, + this.rounded = true, + this.padding, + this.color, + this.textStyle, + this.arrowDirection = ZetaTooltipArrowDirection.down, + this.maxWidth, + }); + + /// The content of the tooltip. + final Widget child; + + /// Determines if the tooltip should have rounded or sharp corners. + /// Default is `true` (rounded). + final bool rounded; + + /// The padding inside the [ZetaTooltip]. + /// Default is: + /// ``` + /// const EdgeInsets.symmetric( + /// horizontal: ZetaSpacing.xs, + /// vertical: ZetaSpacing.xxs, + /// ) + /// ``` + final EdgeInsets? padding; + + /// The color of the tooltip. + /// Default is `zeta.colors.textDefault`. + final Color? color; + + /// The text style of the tooltip. + /// Default is: + /// ``` + /// ZetaTextStyles.bodyXSmall.copyWith( + /// color: zeta.colors.textInverse, + /// fontWeight: FontWeight.w500, + /// ), + /// ``` + final TextStyle? textStyle; + + /// The direction of the tooltip's arrow. + /// Default is `ZetaTooltipArrowDirection.down`. + final ZetaTooltipArrowDirection arrowDirection; + + /// The maximum width of the tooltip. + final double? maxWidth; + + @override + Widget build(BuildContext context) { + final zeta = Zeta.of(context); + final color = this.color ?? zeta.colors.textDefault; + + return LayoutBuilder( + builder: (context, constraints) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (arrowDirection == ZetaTooltipArrowDirection.up) + Center( + child: CustomPaint( + painter: _FilledArrow( + color: color, + direction: arrowDirection, + ), + size: const Size(8, 4), + ), + ), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (arrowDirection == ZetaTooltipArrowDirection.left) + Center( + child: CustomPaint( + painter: _FilledArrow( + color: color, + direction: arrowDirection, + ), + size: const Size(4, 8), + ), + ), + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: maxWidth ?? constraints.maxWidth, + ), + child: DecoratedBox( + decoration: BoxDecoration( + color: color, + borderRadius: rounded ? ZetaRadius.minimal : null, + ), + child: Padding( + padding: padding ?? + const EdgeInsets.symmetric( + horizontal: ZetaSpacing.xs, + vertical: ZetaSpacing.xxs, + ), + child: DefaultTextStyle( + style: textStyle ?? + ZetaTextStyles.bodyXSmall.copyWith( + color: zeta.colors.textInverse, + fontWeight: FontWeight.w500, + ), + child: child, + ), + ), + ), + ), + if (arrowDirection == ZetaTooltipArrowDirection.right) + Center( + child: CustomPaint( + painter: _FilledArrow( + color: color, + direction: arrowDirection, + ), + size: const Size(4, 8), + ), + ), + ], + ), + if (arrowDirection == ZetaTooltipArrowDirection.down) + Center( + child: CustomPaint( + painter: _FilledArrow( + color: color, + direction: arrowDirection, + ), + size: const Size(8, 4), + ), + ), + ], + ); + }, + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('rounded', rounded)) + ..add(DiagnosticsProperty('padding', padding)) + ..add(ColorProperty('color', color)) + ..add(DiagnosticsProperty('textStyle', textStyle)) + ..add(EnumProperty('arrowDirection', arrowDirection)) + ..add(DoubleProperty('maxWidth', maxWidth)); + } +} + +class _FilledArrow extends CustomPainter { + _FilledArrow({ + required this.direction, + this.color, + }); + + final Color? color; + final ZetaTooltipArrowDirection direction; + + @override + void paint(Canvas canvas, Size size) { + final paint = Paint() + ..style = PaintingStyle.fill + ..color = color ?? Colors.transparent; + final path = switch (direction) { + ZetaTooltipArrowDirection.up => Path() + ..moveTo(size.width / 2, 0) + ..lineTo(0, size.height) + ..lineTo(size.width, size.height) + ..lineTo(size.width / 2, 0), + ZetaTooltipArrowDirection.left => Path() + ..moveTo(size.width, 0) + ..lineTo(0, size.height / 2) + ..lineTo(size.width, size.height) + ..lineTo(size.width, 0), + ZetaTooltipArrowDirection.down => Path() + ..lineTo(size.width, 0) + ..lineTo(size.width / 2, size.height) + ..lineTo(0, 0), + ZetaTooltipArrowDirection.right => Path() + ..lineTo(size.width, size.height / 2) + ..lineTo(0, size.height) + ..lineTo(0, 0), + }; + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/lib/zeta_flutter.dart b/lib/zeta_flutter.dart index 9181ca42..3638bf90 100644 --- a/lib/zeta_flutter.dart +++ b/lib/zeta_flutter.dart @@ -41,6 +41,7 @@ export 'src/components/stepper/stepper.dart'; export 'src/components/switch/zeta_switch.dart'; export 'src/components/tabs/tab.dart'; export 'src/components/tabs/tab_bar.dart'; +export 'src/components/tooltip/tooltip.dart'; export 'src/theme/color_extensions.dart'; export 'src/theme/color_scheme.dart'; export 'src/theme/color_swatch.dart'; From adb93ffbf291d8ac915c6cf651f485d9f72488cb Mon Sep 17 00:00:00 2001 From: sd-athlon <163880004+sd-athlon@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:52:18 +0300 Subject: [PATCH 10/15] feat(main): Segmented control (#26) * feat(main): AppBar * Add segmented control * [automated commit] lint format and import sort * Fix mouse cursor, disable selection container and tap area * [automated commit] lint format and import sort --------- Co-authored-by: github-actions --- example/lib/home.dart | 4 + .../components/segmented_control_example.dart | 87 +++ example/widgetbook/main.dart | 5 + .../segmented_control_widgetbook.dart | 64 ++ .../segmented_control/segmented_control.dart | 621 ++++++++++++++++++ lib/zeta_flutter.dart | 1 + 6 files changed, 782 insertions(+) create mode 100644 example/lib/pages/components/segmented_control_example.dart create mode 100644 example/widgetbook/pages/components/segmented_control_widgetbook.dart create mode 100644 lib/src/components/segmented_control/segmented_control.dart diff --git a/example/lib/home.dart b/example/lib/home.dart index de428915..19c12839 100644 --- a/example/lib/home.dart +++ b/example/lib/home.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:zeta_example/pages/components/accordion_example.dart'; +import 'package:zeta_example/pages/components/app_bar_example.dart'; import 'package:zeta_example/pages/components/avatar_example.dart'; import 'package:zeta_example/pages/components/badges_example.dart'; import 'package:zeta_example/pages/components/banner_example.dart'; @@ -18,6 +19,7 @@ import 'package:zeta_example/pages/components/navigation_bar_example.dart'; import 'package:zeta_example/pages/components/navigation_rail_example.dart'; import 'package:zeta_example/pages/components/phone_input_example.dart'; import 'package:zeta_example/pages/components/radio_example.dart'; +import 'package:zeta_example/pages/components/segmented_control_example.dart'; import 'package:zeta_example/pages/components/stepper_example.dart'; import 'package:zeta_example/pages/components/switch_example.dart'; import 'package:zeta_example/pages/components/snackbar_example.dart'; @@ -43,6 +45,7 @@ class Component { final List components = [ Component(AccordionExample.name, (context) => const AccordionExample()), + Component(AppBarExample.name, (context) => const AppBarExample()), Component(AvatarExample.name, (context) => const AvatarExample()), Component(BannerExample.name, (context) => const BannerExample()), Component(BadgesExample.name, (context) => const BadgesExample()), @@ -57,6 +60,7 @@ final List components = [ Component(PasswordInputExample.name, (context) => const PasswordInputExample()), Component(DropdownExample.name, (context) => const DropdownExample()), Component(ProgressExample.name, (context) => const ProgressExample()), + Component(SegmentedControlExample.name, (context) => const SegmentedControlExample()), Component(SnackBarExample.name, (context) => const SnackBarExample()), Component(StepperExample.name, (context) => const StepperExample()), Component(TabsExample.name, (context) => const TabsExample()), diff --git a/example/lib/pages/components/segmented_control_example.dart b/example/lib/pages/components/segmented_control_example.dart new file mode 100644 index 00000000..783e966c --- /dev/null +++ b/example/lib/pages/components/segmented_control_example.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:zeta_example/widgets.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +class SegmentedControlExample extends StatefulWidget { + const SegmentedControlExample({super.key}); + + static const String name = 'SegmentedControl'; + + @override + State createState() => _SegmentedControlExampleState(); +} + +class _SegmentedControlExampleState extends State { + final _iconsSegments = [1, 2, 3, 4, 5]; + final _numberSegments = [1, 2, 3, 4, 5]; + late int _selectedIconSegment = _iconsSegments.first; + late int _selectedNumberSegment = _numberSegments.first; + late String _selectedTextSegment = _textSegments.first; + final _textSegments = ["Item 1", "Item 2", "Item 3"]; + + @override + Widget build(BuildContext context) { + return ExampleScaffold( + name: SegmentedControlExample.name, + child: SingleChildScrollView( + child: Column( + children: [ + // Text + Padding( + padding: const EdgeInsets.all(ZetaSpacing.l), + child: ZetaSegmentedControl( + segments: [ + for (final value in _textSegments) + ZetaButtonSegment( + value: value, + child: Text(value), + ), + ], + onChanged: (value) => setState( + () => _selectedTextSegment = value, + ), + selected: _selectedTextSegment, + ), + ), + + // Numbers + Padding( + padding: const EdgeInsets.all(ZetaSpacing.l), + child: ZetaSegmentedControl( + segments: [ + for (final value in _numberSegments) + ZetaButtonSegment( + value: value, + child: Text(value.toString()), + ), + ], + onChanged: (value) => setState( + () => _selectedNumberSegment = value, + ), + selected: _selectedNumberSegment, + ), + ), + + // Icons + Padding( + padding: const EdgeInsets.all(ZetaSpacing.l), + child: ZetaSegmentedControl( + segments: [ + for (final value in _iconsSegments) + ZetaButtonSegment( + value: value, + child: Icon(ZetaIcons.star_round), + ), + ], + onChanged: (value) => setState( + () => _selectedIconSegment = value, + ), + selected: _selectedIconSegment, + ), + ), + ], + ), + ), + ); + } +} diff --git a/example/widgetbook/main.dart b/example/widgetbook/main.dart index f5975bb9..172069e5 100644 --- a/example/widgetbook/main.dart +++ b/example/widgetbook/main.dart @@ -26,6 +26,7 @@ import 'pages/components/password_input_widgetbook.dart'; import 'pages/components/phone_input_widgetbook.dart'; import 'pages/components/progress_widgetbook.dart'; import 'pages/components/radio_widgetbook.dart'; +import 'pages/components/segmented_control_widgetbook.dart'; import 'pages/components/stepper_widgetbook.dart'; import 'pages/components/switch_widgetbook.dart'; import 'pages/components/snack_bar_widgetbook.dart'; @@ -115,6 +116,10 @@ class HotReload extends StatelessWidget { ], ), WidgetbookUseCase(name: 'Radio Button', builder: (context) => radioButtonUseCase(context)), + WidgetbookUseCase( + name: 'Segmented Control', + builder: (context) => segmentedControlUseCase(context), + ), WidgetbookUseCase(name: 'Switch', builder: (context) => switchUseCase(context)), WidgetbookUseCase( name: 'Snack Bar', diff --git a/example/widgetbook/pages/components/segmented_control_widgetbook.dart b/example/widgetbook/pages/components/segmented_control_widgetbook.dart new file mode 100644 index 00000000..e3544fa7 --- /dev/null +++ b/example/widgetbook/pages/components/segmented_control_widgetbook.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +import '../../test/test_components.dart'; +import '../../utils/utils.dart'; + +Widget segmentedControlUseCase(BuildContext context) { + final iconsSegments = List.generate(5, (index) => index); + int selectedIconSegment = iconsSegments.first; + + final rounded = context.knobs.boolean(label: "Rounded", initialValue: true); + final icon = iconKnob(context, rounded: rounded, initial: ZetaIcons.star_round); + + final text = context.knobs.string(label: 'Text', initialValue: "Item"); + + final textSegments = List.generate(3, (index) => "$text ${index + 1}"); + String selectedTextSegment = textSegments.first; + + return WidgetbookTestWidget( + widget: StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(ZetaSpacing.l), + child: ZetaSegmentedControl( + rounded: rounded, + segments: [ + for (final value in iconsSegments) + ZetaButtonSegment( + value: value, + child: Icon(icon), + ), + ], + onChanged: (value) => setState( + () => selectedIconSegment = value, + ), + selected: selectedIconSegment, + ), + ), + Padding( + padding: const EdgeInsets.all(ZetaSpacing.l), + child: ZetaSegmentedControl( + rounded: rounded, + segments: [ + for (final value in textSegments) + ZetaButtonSegment( + value: value, + child: Text( + value, + ), + ), + ], + onChanged: (value) => setState( + () => selectedTextSegment = value, + ), + selected: selectedTextSegment, + ), + ), + ], + ); + }), + ); +} diff --git a/lib/src/components/segmented_control/segmented_control.dart b/lib/src/components/segmented_control/segmented_control.dart new file mode 100644 index 00000000..43868eec --- /dev/null +++ b/lib/src/components/segmented_control/segmented_control.dart @@ -0,0 +1,621 @@ +import 'dart:math' as math; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/physics.dart'; +import 'package:flutter/rendering.dart'; +import '../../../zeta_flutter.dart'; + +/// Creates an segmented control bar. +class ZetaSegmentedControl extends StatefulWidget { + /// Constructs an segmented control bar. + const ZetaSegmentedControl({ + required this.segments, + required this.onChanged, + required this.selected, + this.rounded = true, + super.key, + }); + + /// The callback that is called when a new option is tapped. + final void Function(T)? onChanged; + + /// Whether the corners to be rounded. + final bool rounded; + + /// Descriptions of the segments in the button. + final List> segments; + + /// Currently selected segment. + final T selected; + + @override + State> createState() => _ZetaSegmentedControlState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add( + ObjectFlagProperty.has('onChanged', onChanged), + ) + ..add(DiagnosticsProperty('rounded', rounded)) + ..add(IterableProperty>('segments', segments)) + ..add(DiagnosticsProperty('selected', selected)); + } +} + +class _ZetaSegmentedControlState extends State> + with TickerProviderStateMixin> { + T? _highlighted; + Animatable? _thumbAnimatable; + late final AnimationController _thumbController = AnimationController( + duration: kThemeAnimationDuration, + value: 0, + vsync: this, + ); + + late final _thumbScaleAnimation = _thumbScaleController.drive(Tween(begin: 1)); + + late final _thumbScaleController = AnimationController( + duration: kThemeAnimationDuration, + value: 0, + vsync: this, + ); + + @override + void initState() { + super.initState(); + + _highlighted = widget.selected; + } + + @override + void didUpdateWidget(ZetaSegmentedControl oldWidget) { + super.didUpdateWidget(oldWidget); + + if (_highlighted != widget.selected) { + _thumbController.animateWith( + SpringSimulation( + const SpringDescription(mass: 1, stiffness: 500, damping: 44), + 0, + 1, + 0, // Every time a new spring animation starts the previous animation stops. + ), + ); + _thumbAnimatable = null; + _highlighted = widget.selected; + } + } + + @override + void dispose() { + _thumbScaleController.dispose(); + _thumbController.dispose(); + + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final List children = []; + int index = 0; + int? highlightedIndex; + for (final segment in widget.segments) { + final isHighlighted = _highlighted == segment.value; + if (isHighlighted) highlightedIndex = index; + + if (index != 0) { + children.add(SizedBox(key: Key(index.toString()))); + } + + children.add( + _Segment( + key: ValueKey(segment.value), + rounded: widget.rounded, + child: segment.child, + onTap: () => widget.onChanged?.call(segment.value), + ), + ); + + index += 1; + } + + final colors = Zeta.of(context).colors; + + return MouseRegion( + cursor: kIsWeb ? SystemMouseCursors.click : MouseCursor.defer, + child: SelectionContainer.disabled( + child: Container( + padding: const EdgeInsets.all(ZetaSpacing.xxs), + decoration: BoxDecoration( + color: colors.surfaceDisabled, + borderRadius: widget.rounded ? ZetaRadius.minimal : ZetaRadius.none, + ), + child: AnimatedBuilder( + animation: _thumbScaleAnimation, + builder: (BuildContext context, Widget? child) { + return _SegmentedControlRenderWidget( + highlightedIndex: highlightedIndex, + thumbColor: colors.surfacePrimary, + thumbScale: _thumbScaleAnimation.value, + rounded: widget.rounded, + state: this, + children: children, + ); + }, + ), + ), + ), + ); + } +} + +/// Data describing a segment of a [ZetaSegmentedControl]. +class ZetaButtonSegment { + /// Construct a [ZetaButtonSegment]. + const ZetaButtonSegment({ + required this.value, + required this.child, + }); + + /// The child to be displayed + final Widget child; + + /// Value used to identify the segment. + /// + /// This value must be unique across all segments. + final T value; +} + +class _Segment extends StatefulWidget { + const _Segment({ + required ValueKey key, + required this.child, + required this.rounded, + required this.onTap, + }) : super(key: key); + + final Widget child; + final bool rounded; + final VoidCallback onTap; + + @override + _SegmentState createState() => _SegmentState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('rounded', rounded)) + ..add(ObjectFlagProperty.has('onTap', onTap)); + } +} + +class _SegmentState extends State<_Segment> with TickerProviderStateMixin<_Segment> { + @override + Widget build(BuildContext context) { + final colors = Zeta.of(context).colors; + + return Material( + color: Colors.transparent, + child: InkWell( + splashFactory: NoSplash.splashFactory, + borderRadius: widget.rounded ? ZetaRadius.minimal : ZetaRadius.none, + onTap: widget.onTap, + child: IndexedStack( + alignment: Alignment.center, + children: [ + widget.child, + IconTheme( + data: const IconThemeData(size: ZetaSpacing.x5), + child: DefaultTextStyle( + style: ZetaTextStyles.labelMedium.copyWith( + color: colors.textDefault, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: ZetaSpacing.l, + vertical: ZetaSpacing.xxs, + ), + child: widget.child, + ), + ), + ), + ], + ), + ), + ); + } +} + +class _SegmentedControlRenderWidget extends MultiChildRenderObjectWidget { + const _SegmentedControlRenderWidget({ + super.key, + super.children, + required this.highlightedIndex, + required this.thumbColor, + required this.thumbScale, + required this.state, + required this.rounded, + }); + + final int? highlightedIndex; + final bool rounded; + final _ZetaSegmentedControlState state; + final Color thumbColor; + final double thumbScale; + + @override + RenderObject createRenderObject(BuildContext context) { + return _RenderSegmentedControl( + highlightedIndex: highlightedIndex, + thumbColor: thumbColor, + rounded: rounded, + state: state, + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(IntProperty('highlightedIndex', highlightedIndex)) + ..add(DiagnosticsProperty('rounded', rounded)) + ..add(DiagnosticsProperty<_ZetaSegmentedControlState>('state', state)) + ..add(ColorProperty('thumbColor', thumbColor)) + ..add(DoubleProperty('thumbScale', thumbScale)); + } + + @override + void updateRenderObject( + BuildContext context, + _RenderSegmentedControl renderObject, + ) { + renderObject + ..thumbColor = thumbColor + ..highlightedIndex = highlightedIndex; + } +} + +class _SegmentedControlContainerBoxParentData extends ContainerBoxParentData {} + +class _RenderSegmentedControl extends RenderBox + with + ContainerRenderObjectMixin>, + RenderBoxContainerDefaultsMixin> { + _RenderSegmentedControl({ + required int? highlightedIndex, + required Color thumbColor, + required this.rounded, + required this.state, + }) : _highlightedIndex = highlightedIndex, + _thumbColor = thumbColor; + + // The current **Unscaled** Thumb Rect in this RenderBox's coordinate space. + Rect? currentThumbRect; + + /// Wether the corners to be rounded. + final bool rounded; + + // Paint the separator to the right of the given child. + final Paint separatorPaint = Paint(); + + final _ZetaSegmentedControlState state; + + int? _highlightedIndex; + Color _thumbColor; + + @override + void attach(PipelineOwner owner) { + super.attach(owner); + state._thumbController.addListener(markNeedsPaint); + } + + @override + double? computeDistanceToActualBaseline(TextBaseline baseline) { + return defaultComputeDistanceToHighestActualBaseline(baseline); + } + + @override + Size computeDryLayout(BoxConstraints constraints) { + final Size childSize = _calculateChildSize(constraints); + return _computeOverallSizeFromChildSize(childSize, constraints); + } + + @override + double computeMaxIntrinsicHeight(double width) { + RenderBox? child = firstChild; + double maxMaxChildHeight = ZetaSpacing.x7; + while (child != null) { + final double childHeight = child.getMaxIntrinsicHeight(width); + maxMaxChildHeight = math.max(maxMaxChildHeight, childHeight); + child = nonSeparatorChildAfter(child); + } + return maxMaxChildHeight; + } + + @override + double computeMaxIntrinsicWidth(double height) { + final int childCount = this.childCount ~/ 2 + 1; + RenderBox? child = firstChild; + double maxMaxChildWidth = 0; + while (child != null) { + final double childWidth = child.getMaxIntrinsicWidth(height); + maxMaxChildWidth = math.max(maxMaxChildWidth, childWidth); + child = nonSeparatorChildAfter(child); + } + return maxMaxChildWidth * childCount + totalSeparatorWidth; + } + + @override + double computeMinIntrinsicHeight(double width) { + RenderBox? child = firstChild; + double maxMinChildHeight = ZetaSpacing.x7; + while (child != null) { + final double childHeight = child.getMinIntrinsicHeight(width); + maxMinChildHeight = math.max(maxMinChildHeight, childHeight); + child = nonSeparatorChildAfter(child); + } + return maxMinChildHeight; + } + + @override + double computeMinIntrinsicWidth(double height) { + final int childCount = this.childCount ~/ 2 + 1; + RenderBox? child = firstChild; + double maxMinChildWidth = 0; + while (child != null) { + final double childWidth = child.getMinIntrinsicWidth(height); + maxMinChildWidth = math.max(maxMinChildWidth, childWidth); + child = nonSeparatorChildAfter(child); + } + return (maxMinChildWidth + 2 * ZetaSpacing.l) * childCount + totalSeparatorWidth; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('currentThumbRect', currentThumbRect)) + ..add(DiagnosticsProperty('rounded', rounded)) + ..add(DiagnosticsProperty('separatorPaint', separatorPaint)) + ..add(DiagnosticsProperty<_ZetaSegmentedControlState>('state', state)) + ..add(IntProperty('highlightedIndex', highlightedIndex)) + ..add(ColorProperty('thumbColor', thumbColor)) + ..add(DoubleProperty('totalSeparatorWidth', totalSeparatorWidth)); + } + + @override + void detach() { + state._thumbController.removeListener(markNeedsPaint); + super.detach(); + } + + @override + bool hitTestChildren(BoxHitTestResult result, {required Offset position}) { + RenderBox? child = lastChild; + while (child != null) { + final _SegmentedControlContainerBoxParentData childParentData = + child.parentData! as _SegmentedControlContainerBoxParentData; + if ((childParentData.offset & child.size).contains(position)) { + return result.addWithPaintOffset( + offset: childParentData.offset, + position: position, + hitTest: (BoxHitTestResult result, Offset localOffset) { + return child!.hitTest(result, position: localOffset); + }, + ); + } + child = childParentData.previousSibling; + } + return false; + } + + @override + void paint(PaintingContext context, Offset offset) { + final List children = getChildrenAsList(); + + for (int index = 1; index < childCount; index += 2) { + _paintSeparator(context, offset, children[index]); + } + + final int? highlightedChildIndex = highlightedIndex; + // Paint thumb if there's a highlighted segment. + if (highlightedChildIndex != null) { + final RenderBox selectedChild = children[highlightedChildIndex * 2]; + + final _SegmentedControlContainerBoxParentData childParentData = + selectedChild.parentData! as _SegmentedControlContainerBoxParentData; + final newThumbRect = childParentData.offset & selectedChild.size; + + // Update thumb animation's tween, in case the end rect changed (e.g., a + // new segment is added during the animation). + if (state._thumbController.isAnimating) { + final Animatable? thumbTween = state._thumbAnimatable; + if (thumbTween == null) { + // This is the first frame of the animation. + final Rect startingRect = moveThumbRectInBound(currentThumbRect, children) ?? newThumbRect; + state._thumbAnimatable = RectTween(begin: startingRect, end: newThumbRect); + } else if (newThumbRect != thumbTween.transform(1)) { + // The thumbTween of the running sliding animation needs updating, + // without restarting the animation. + final Rect startingRect = moveThumbRectInBound(currentThumbRect, children) ?? newThumbRect; + state._thumbAnimatable = RectTween(begin: startingRect, end: newThumbRect).chain( + CurveTween(curve: Interval(state._thumbController.value, 1)), + ); + } + } else { + state._thumbAnimatable = null; + } + + final Rect unscaledThumbRect = state._thumbAnimatable?.evaluate(state._thumbController) ?? newThumbRect; + currentThumbRect = unscaledThumbRect; + final Rect thumbRect = Rect.fromCenter( + center: unscaledThumbRect.center, + width: unscaledThumbRect.width, + height: unscaledThumbRect.height, + ); + + _paintThumb(context, offset, thumbRect); + } else { + currentThumbRect = null; + } + + for (int index = 0; index < children.length; index += 2) { + _paintChild(context, offset, children[index]); + } + } + + @override + void performLayout() { + final BoxConstraints constraints = this.constraints; + final Size childSize = _calculateChildSize(constraints); + final BoxConstraints childConstraints = BoxConstraints.tight(childSize); + final BoxConstraints separatorConstraints = childConstraints.heightConstraints(); + + RenderBox? child = firstChild; + int index = 0; + double start = 0; + while (child != null) { + child.layout( + index.isEven ? childConstraints : separatorConstraints, + parentUsesSize: true, + ); + final _SegmentedControlContainerBoxParentData childParentData = + child.parentData! as _SegmentedControlContainerBoxParentData; + final Offset childOffset = Offset(start, 0); + childParentData.offset = childOffset; + start += child.size.width; + + child = childAfter(child); + index += 1; + } + + size = _computeOverallSizeFromChildSize(childSize, constraints); + } + + @override + void setupParentData(RenderBox child) { + if (child.parentData is! _SegmentedControlContainerBoxParentData) { + child.parentData = _SegmentedControlContainerBoxParentData(); + } + } + + int? get highlightedIndex => _highlightedIndex; + + set highlightedIndex(int? value) { + if (_highlightedIndex == value) { + return; + } + + _highlightedIndex = value; + markNeedsPaint(); + } + + Color get thumbColor => _thumbColor; + + set thumbColor(Color value) { + if (_thumbColor == value) { + return; + } + _thumbColor = value; + markNeedsPaint(); + } + + double get totalSeparatorWidth => 0.0 * (childCount ~/ 2); + + RenderBox? nonSeparatorChildAfter(RenderBox child) { + final RenderBox? nextChild = childAfter(child); + return nextChild == null ? null : childAfter(nextChild); + } + + // This method is used to convert the original unscaled thumb rect painted in + // the previous frame, to a Rect that is within the valid boundary defined by + // the child segments. + // + // The overall size does not include that of the thumb. That is, if the thumb + // is located at the first or the last segment, the thumb can get cut off if + // one of the values in _kThumbInsets is positive. + Rect? moveThumbRectInBound(Rect? thumbRect, List children) { + if (thumbRect == null) { + return null; + } + + final Offset firstChildOffset = (children.first.parentData! as _SegmentedControlContainerBoxParentData).offset; + final double leftMost = firstChildOffset.dx; + final double rightMost = + (children.last.parentData! as _SegmentedControlContainerBoxParentData).offset.dx + children.last.size.width; + + // Ignore the horizontal position and the height of `thumbRect`, and + // calculates them from `children`. + return Rect.fromLTRB( + math.max(thumbRect.left, leftMost), + firstChildOffset.dy, + math.min(thumbRect.right, rightMost), + firstChildOffset.dy + children.first.size.height, + ); + } + + Size _calculateChildSize(BoxConstraints constraints) { + final int childCount = this.childCount ~/ 2 + 1; + double childWidth = (constraints.minWidth - totalSeparatorWidth) / childCount; + double maxHeight = ZetaSpacing.x7; + RenderBox? child = firstChild; + while (child != null) { + childWidth = math.max(childWidth, child.getMaxIntrinsicWidth(double.infinity) + 2); + child = nonSeparatorChildAfter(child); + } + childWidth = math.min( + childWidth, + (constraints.maxWidth - totalSeparatorWidth) / childCount, + ); + child = firstChild; + while (child != null) { + final double boxHeight = child.getMaxIntrinsicHeight(childWidth); + maxHeight = math.max(maxHeight, boxHeight); + child = nonSeparatorChildAfter(child); + } + return Size(childWidth, maxHeight); + } + + Size _computeOverallSizeFromChildSize( + Size childSize, + BoxConstraints constraints, + ) { + final int childCount = this.childCount ~/ 2 + 1; + return constraints.constrain( + Size( + childSize.width * childCount + totalSeparatorWidth, + childSize.height, + ), + ); + } + + void _paintSeparator( + PaintingContext context, + Offset offset, + RenderBox child, + ) { + final _SegmentedControlContainerBoxParentData childParentData = + child.parentData! as _SegmentedControlContainerBoxParentData; + context.paintChild(child, offset + childParentData.offset); + } + + void _paintChild(PaintingContext context, Offset offset, RenderBox child) { + final _SegmentedControlContainerBoxParentData childParentData = + child.parentData! as _SegmentedControlContainerBoxParentData; + context.paintChild(child, childParentData.offset + offset); + } + + void _paintThumb(PaintingContext context, Offset offset, Rect thumbRect) { + final RRect thumbRRect = RRect.fromRectAndRadius( + thumbRect.shift(offset), + rounded ? ZetaRadius.minimal.topLeft : ZetaRadius.none.topLeft, + ); + + context.canvas.drawRRect( + thumbRRect, + Paint()..color = thumbColor, + ); + } +} diff --git a/lib/zeta_flutter.dart b/lib/zeta_flutter.dart index 3638bf90..b722a8b3 100644 --- a/lib/zeta_flutter.dart +++ b/lib/zeta_flutter.dart @@ -36,6 +36,7 @@ export 'src/components/phone_input/phone_input.dart'; export 'src/components/progress/progress_bar.dart'; export 'src/components/progress/progress_circle.dart'; export 'src/components/radio/radio.dart'; +export 'src/components/segmented_control/segmented_control.dart'; export 'src/components/snack_bar/snack_bar.dart'; export 'src/components/stepper/stepper.dart'; export 'src/components/switch/zeta_switch.dart'; From da13199645872f820025547861e606e3a62d72a6 Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:11:41 +0300 Subject: [PATCH 11/15] Component phone input (#28) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * ZetaPhoneInput initial commit * complete ZetaPhoneInput; add flags * create phoneInputUseCase in Widgetbook * refactor phone input to use native alert dialog * don't use root navigator in widgetbook * pass parameter useRootNavigator * restore some missing countries in the list * countries search * add searchHint * fix comments --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> --- .../phone_input/countries_dialog.dart | 165 +++++++++++++++--- .../components/phone_input/phone_input.dart | 13 +- 2 files changed, 148 insertions(+), 30 deletions(-) diff --git a/lib/src/components/phone_input/countries_dialog.dart b/lib/src/components/phone_input/countries_dialog.dart index 92919ad9..2f7876db 100644 --- a/lib/src/components/phone_input/countries_dialog.dart +++ b/lib/src/components/phone_input/countries_dialog.dart @@ -1,9 +1,10 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import '../../../zeta_flutter.dart'; +import 'countries.dart'; /// Class for [CountriesDialog] -class CountriesDialog extends StatefulWidget { +class CountriesDialog extends StatefulWidget { ///Constructor of [CountriesDialog] const CountriesDialog({ super.key, @@ -12,6 +13,7 @@ class CountriesDialog extends StatefulWidget { required this.items, required this.onChanged, this.enabled = true, + this.searchHint, this.useRootNavigator = true, }); @@ -21,46 +23,52 @@ class CountriesDialog extends StatefulWidget { /// The button, which opens the dialog. final Widget button; - /// List of [DropdownMenuItem] - final List> items; + /// List of [CountriesMenuItem] + final List items; /// Called when an item is selected. - final ValueSetter onChanged; + final ValueSetter onChanged; /// Determines if the button should be enabled (default) or disabled. final bool enabled; + /// The hint to be shown inside the country search input field. + /// Default is `Search by name or dial code`. + final String? searchHint; + /// Determines if the root navigator should be used. final bool useRootNavigator; @override - State> createState() => _CountriesDialogState(); + State createState() => _CountriesDialogState(); @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties - ..add(IterableProperty>('items', items)) - ..add(ObjectFlagProperty>.has('onChanged', onChanged)) + ..add(IterableProperty('items', items)) + ..add(ObjectFlagProperty>.has('onChanged', onChanged)) ..add(DiagnosticsProperty('enabled', enabled)) - ..add(DiagnosticsProperty('useRootNavigator', useRootNavigator)); + ..add(DiagnosticsProperty('useRootNavigator', useRootNavigator)) + ..add(StringProperty('searchHint', searchHint)); } } -class _CountriesDialogState extends State> { - Future _showCountriesDialog( +class _CountriesDialogState extends State { + Future _showCountriesDialog( BuildContext context, { Zeta? zeta, - required List> items, + required List items, bool barrierDismissible = true, bool useRootNavigator = true, }) => - showDialog( + showDialog( context: context, barrierDismissible: barrierDismissible, useRootNavigator: useRootNavigator, builder: (_) => _CountriesList( items: items, + searchHint: widget.searchHint, zeta: zeta, ), ); @@ -84,40 +92,143 @@ class _CountriesDialogState extends State> { } } -class _CountriesList extends StatelessWidget { +class _CountriesList extends StatefulWidget { const _CountriesList({ required this.items, + this.searchHint, this.zeta, }); final Zeta? zeta; - final List> items; + final List items; + final String? searchHint; + + @override + State<_CountriesList> createState() => _CountriesListState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(IterableProperty('items', items)) + ..add(StringProperty('searchHint', searchHint)); + } +} + +class _CountriesListState extends State<_CountriesList> { + late final bool _enableSearch = widget.items.length > 20; + final _controller = TextEditingController(); + List _items = []; + + @override + void initState() { + super.initState(); + _items = List.from(widget.items); + } + + void _search(String value) { + setState(() { + _items = widget.items.where((item) { + return item.value.name.toLowerCase().contains(value.toLowerCase()) || + (RegExp(r'^\d+$').hasMatch(value) && item.value.dialCode.indexOf('+$value') == 0); + }).toList(); + }); + } + + void _clearSearch() { + _controller.clear(); + setState(() { + _items = List.from(widget.items); + }); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } @override Widget build(BuildContext context) { - final zeta = this.zeta ?? Zeta.of(context); + final zeta = widget.zeta ?? Zeta.of(context); return AlertDialog( surfaceTintColor: zeta.colors.surfacePrimary, shape: const RoundedRectangleBorder(borderRadius: ZetaRadius.large), content: SizedBox( width: double.maxFinite, - child: ListView.builder( - shrinkWrap: true, - itemCount: items.length, - itemBuilder: (_, index) => InkWell( - onTap: () { - Navigator.of(context).pop(items[index].value); - }, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: ZetaSpacing.xs, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (_enableSearch) + Padding( + padding: const EdgeInsets.only(bottom: ZetaSpacing.b), + child: TextField( + controller: _controller, + onChanged: _search, + decoration: InputDecoration( + hintText: widget.searchHint ?? 'Search by name or dial code', + prefixIcon: const Icon(ZetaIcons.search_round), + suffixIcon: _controller.text.isEmpty + ? null + : IconButton( + onPressed: _clearSearch, + icon: Icon( + ZetaIcons.cancel_round, + color: zeta.colors.cool.shade70, + ), + ), + ), + ), + ), + if (_enableSearch) + Expanded( + child: _listView(context), + ) + else + _listView(context), + Padding( + padding: const EdgeInsets.only(top: ZetaSpacing.b), + child: TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Close'), ), - child: items[index].child, ), - ), + ], ), ), ); } + + Widget _listView(BuildContext context) => ListView.builder( + shrinkWrap: true, + itemCount: _items.length, + itemBuilder: (_, index) => InkWell( + onTap: () { + Navigator.of(context).pop(_items[index].value); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: ZetaSpacing.xs, + ), + child: _items[index].child, + ), + ), + ); +} + +/// [CountriesMenuItem] +/// Item for the country selection dialog. +class CountriesMenuItem { + /// Constructor for [CountriesMenuItem]. + const CountriesMenuItem({ + required this.value, + required this.child, + }); + + /// The selected value from the list. + final Country value; + + /// The widget which will represent each item in the list. + final Widget child; } diff --git a/lib/src/components/phone_input/phone_input.dart b/lib/src/components/phone_input/phone_input.dart index e853e99a..ac347360 100644 --- a/lib/src/components/phone_input/phone_input.dart +++ b/lib/src/components/phone_input/phone_input.dart @@ -20,6 +20,7 @@ class ZetaPhoneInput extends StatefulWidget { this.countryDialCode, this.phoneNumber, this.countries, + this.countrySearchHint, this.useRootNavigator = true, }); @@ -56,6 +57,10 @@ class ZetaPhoneInput extends StatefulWidget { /// List of countries ISO 3166-1 alpha-2 codes final List? countries; + /// The hint to be shown inside the country search input field. + /// Default is `Search by name or dial code`. + final String? countrySearchHint; + /// Determines if the root navigator should be used in the [CountriesDialog]. final bool useRootNavigator; @@ -75,7 +80,8 @@ class ZetaPhoneInput extends StatefulWidget { ..add(StringProperty('countryDialCode', countryDialCode)) ..add(StringProperty('phoneNumber', phoneNumber)) ..add(IterableProperty('countries', countries)) - ..add(DiagnosticsProperty('useRootNavigator', useRootNavigator)); + ..add(DiagnosticsProperty('useRootNavigator', useRootNavigator)) + ..add(StringProperty('countrySearchHint', countrySearchHint)); } } @@ -173,10 +179,11 @@ class _ZetaPhoneInputState extends State { left: BorderSide(color: zeta.colors.cool.shade40), ), ), - child: CountriesDialog( + child: CountriesDialog( zeta: zeta, useRootNavigator: widget.useRootNavigator, enabled: widget.enabled, + searchHint: widget.countrySearchHint, button: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -201,7 +208,7 @@ class _ZetaPhoneInputState extends State { ), items: _countries .map( - (country) => DropdownMenuItem( + (country) => CountriesMenuItem( value: country, child: Row( children: [ From b04527ca0389390213f6390de8afad92106ec168 Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:13:06 +0300 Subject: [PATCH 12/15] use ZetaWidgetSize from enums.dart (#32) --- .../pages/components/date_input_example.dart | 4 +- .../components/date_input_widgetbook.dart | 4 +- lib/src/components/date_input/date_input.dart | 40 +++++++------------ 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/example/lib/pages/components/date_input_example.dart b/example/lib/pages/components/date_input_example.dart index 83ac0812..d02d5d9e 100644 --- a/example/lib/pages/components/date_input_example.dart +++ b/example/lib/pages/components/date_input_example.dart @@ -82,7 +82,7 @@ class _DateInputExampleState extends State { label: 'Label', hint: 'Default hint text', errorText: 'Oops! Error hint text', - size: ZetaDateInputSize.medium, + size: ZetaWidgetSize.medium, ), ), Divider(color: Colors.grey[200]), @@ -96,7 +96,7 @@ class _DateInputExampleState extends State { label: 'Label', hint: 'Default hint text', errorText: 'Oops! Error hint text', - size: ZetaDateInputSize.small, + size: ZetaWidgetSize.small, ), ), ], diff --git a/example/widgetbook/pages/components/date_input_widgetbook.dart b/example/widgetbook/pages/components/date_input_widgetbook.dart index eb3d7cf1..5e85be3a 100644 --- a/example/widgetbook/pages/components/date_input_widgetbook.dart +++ b/example/widgetbook/pages/components/date_input_widgetbook.dart @@ -16,9 +16,9 @@ Widget dateInputUseCase(BuildContext context) { ); final rounded = context.knobs.boolean(label: 'Rounded', initialValue: true); final enabled = context.knobs.boolean(label: 'Enabled', initialValue: true); - final size = context.knobs.list( + final size = context.knobs.list( label: 'Size', - options: ZetaDateInputSize.values, + options: ZetaWidgetSize.values, labelBuilder: (size) => size.name, ); final datePattern = context.knobs.list( diff --git a/lib/src/components/date_input/date_input.dart b/lib/src/components/date_input/date_input.dart index 83c07811..aa7a980f 100644 --- a/lib/src/components/date_input/date_input.dart +++ b/lib/src/components/date_input/date_input.dart @@ -4,18 +4,6 @@ import 'package:intl/intl.dart'; import 'package:mask_text_input_formatter/mask_text_input_formatter.dart'; import '../../../zeta_flutter.dart'; -/// [ZetaDateInput] size -enum ZetaDateInputSize { - /// [large] 48 pixels height of the input field. - large, - - /// [medium] 40 pixels height of the input field. - medium, - - /// [small] 32 pixels height of the input field. - small, -} - /// ZetaDateInput allows entering date in a pre-defined format. /// Validation is performed to make sure the date is valid /// and is in the proper format. @@ -57,7 +45,7 @@ class ZetaDateInput extends StatefulWidget { /// Determines the size of the input field. /// Default is `ZetaDateInputSize.large` - final ZetaDateInputSize? size; + final ZetaWidgetSize? size; /// If provided, displays a label above the input field. final String? label; @@ -102,7 +90,7 @@ class ZetaDateInput extends StatefulWidget { void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties - ..add(EnumProperty('size', size)) + ..add(EnumProperty('size', size)) ..add(StringProperty('label', label)) ..add(StringProperty('hint', hint)) ..add(DiagnosticsProperty('enabled', enabled)) @@ -116,7 +104,7 @@ class ZetaDateInput extends StatefulWidget { class _ZetaDateInputState extends State { final _controller = TextEditingController(); - late ZetaDateInputSize _size; + late ZetaWidgetSize _size; late final String _hintText; late final MaskTextInputFormatter _dateFormatter; bool _invalidDate = false; @@ -141,7 +129,7 @@ class _ZetaDateInputState extends State { } void _setParams() { - _size = widget.size ?? ZetaDateInputSize.large; + _size = widget.size ?? ZetaWidgetSize.large; _hasError = widget.hasError; } @@ -197,7 +185,7 @@ class _ZetaDateInputState extends State { inputFormatters: [_dateFormatter], keyboardType: TextInputType.number, onChanged: (_) => _onChanged(), - style: _size == ZetaDateInputSize.small ? ZetaTextStyles.bodyXSmall : ZetaTextStyles.bodyMedium, + style: _size == ZetaWidgetSize.small ? ZetaTextStyles.bodyXSmall : ZetaTextStyles.bodyMedium, decoration: InputDecoration( isDense: true, contentPadding: EdgeInsets.symmetric( @@ -235,7 +223,7 @@ class _ZetaDateInputState extends State { minHeight: ZetaSpacing.m, minWidth: ZetaSpacing.m, ), - hintStyle: _size == ZetaDateInputSize.small + hintStyle: _size == ZetaWidgetSize.small ? ZetaTextStyles.bodyXSmall.copyWith( color: widget.enabled ? zeta.colors.textDefault : zeta.colors.cool.shade50, ) @@ -289,16 +277,16 @@ class _ZetaDateInputState extends State { ); } - double _inputVerticalPadding(ZetaDateInputSize size) => switch (size) { - ZetaDateInputSize.large => ZetaSpacing.x3, - ZetaDateInputSize.medium => ZetaSpacing.x2, - ZetaDateInputSize.small => ZetaSpacing.x2, + double _inputVerticalPadding(ZetaWidgetSize size) => switch (size) { + ZetaWidgetSize.large => ZetaSpacing.x3, + ZetaWidgetSize.medium => ZetaSpacing.x2, + ZetaWidgetSize.small => ZetaSpacing.x2, }; - double _iconSize(ZetaDateInputSize size) => switch (size) { - ZetaDateInputSize.large => ZetaSpacing.x6, - ZetaDateInputSize.medium => ZetaSpacing.x5, - ZetaDateInputSize.small => ZetaSpacing.x4, + double _iconSize(ZetaWidgetSize size) => switch (size) { + ZetaWidgetSize.large => ZetaSpacing.x6, + ZetaWidgetSize.medium => ZetaSpacing.x5, + ZetaWidgetSize.small => ZetaSpacing.x4, }; OutlineInputBorder _defaultInputBorder( From 36d69d8a76b1046ea43663b5c8d83f3578d2059d Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:13:47 +0300 Subject: [PATCH 13/15] Component tooltip (#33) * create tooltip * create Widgetbook for ZetaTooltip * add LayoutBuilder * [automated commit] lint format and import sort * fix text overflow when there is horizontal arrow and maxWidth is null --------- Co-authored-by: github-actions --- lib/src/components/tooltip/tooltip.dart | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/src/components/tooltip/tooltip.dart b/lib/src/components/tooltip/tooltip.dart index b98eb2c9..8f2fcc41 100644 --- a/lib/src/components/tooltip/tooltip.dart +++ b/lib/src/components/tooltip/tooltip.dart @@ -3,6 +3,9 @@ import 'package:flutter/rendering.dart'; import '../../../zeta_flutter.dart'; +const _horizontalArrowSize = Size(4, 8); +const _verticalArrowSize = Size(8, 4); + /// The direction of [ZetaTooltip]'s arrow enum ZetaTooltipArrowDirection { /// [up] @@ -74,6 +77,10 @@ class ZetaTooltip extends StatelessWidget { Widget build(BuildContext context) { final zeta = Zeta.of(context); final color = this.color ?? zeta.colors.textDefault; + final horizontalArrowWidth = + [ZetaTooltipArrowDirection.left, ZetaTooltipArrowDirection.right].contains(arrowDirection) + ? _horizontalArrowSize.width + : 0; return LayoutBuilder( builder: (context, constraints) { @@ -87,7 +94,7 @@ class ZetaTooltip extends StatelessWidget { color: color, direction: arrowDirection, ), - size: const Size(8, 4), + size: _verticalArrowSize, ), ), Row( @@ -100,12 +107,12 @@ class ZetaTooltip extends StatelessWidget { color: color, direction: arrowDirection, ), - size: const Size(4, 8), + size: _horizontalArrowSize, ), ), ConstrainedBox( constraints: BoxConstraints( - maxWidth: maxWidth ?? constraints.maxWidth, + maxWidth: maxWidth ?? (constraints.maxWidth - horizontalArrowWidth), ), child: DecoratedBox( decoration: BoxDecoration( @@ -136,7 +143,7 @@ class ZetaTooltip extends StatelessWidget { color: color, direction: arrowDirection, ), - size: const Size(4, 8), + size: _horizontalArrowSize, ), ), ], @@ -148,7 +155,7 @@ class ZetaTooltip extends StatelessWidget { color: color, direction: arrowDirection, ), - size: const Size(8, 4), + size: _verticalArrowSize, ), ), ], From 1f4eee7292cbe36ebeb98292fa31bf618634316a Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:14:49 +0300 Subject: [PATCH 14/15] Component search bar (#29) * create ZetaSearchBar with examples * create Widgetbook for ZetaSearchBar * rename callback * full instead of stadium shape * default hint Search * add parameters showLeadingIcon & showSpeechToText * fix comments * use ZetaWidgetBorder & ZetaWidgetSize from enums.dart --- example/lib/home.dart | 2 + .../pages/components/search_bar_example.dart | 89 +++++++ example/widgetbook/main.dart | 2 + .../components/search_bar_widgetbook.dart | 80 ++++++ lib/src/components/search_bar/search_bar.dart | 238 ++++++++++++++++++ lib/zeta_flutter.dart | 1 + 6 files changed, 412 insertions(+) create mode 100644 example/lib/pages/components/search_bar_example.dart create mode 100644 example/widgetbook/pages/components/search_bar_widgetbook.dart create mode 100644 lib/src/components/search_bar/search_bar.dart diff --git a/example/lib/home.dart b/example/lib/home.dart index 19c12839..a0b93d43 100644 --- a/example/lib/home.dart +++ b/example/lib/home.dart @@ -19,6 +19,7 @@ import 'package:zeta_example/pages/components/navigation_bar_example.dart'; import 'package:zeta_example/pages/components/navigation_rail_example.dart'; import 'package:zeta_example/pages/components/phone_input_example.dart'; import 'package:zeta_example/pages/components/radio_example.dart'; +import 'package:zeta_example/pages/components/search_bar_example.dart'; import 'package:zeta_example/pages/components/segmented_control_example.dart'; import 'package:zeta_example/pages/components/stepper_example.dart'; import 'package:zeta_example/pages/components/switch_example.dart'; @@ -70,6 +71,7 @@ final List components = [ Component(DateInputExample.name, (context) => const DateInputExample()), Component(PhoneInputExample.name, (context) => const PhoneInputExample()), Component(DialogExample.name, (context) => const DialogExample()), + Component(SearchBarExample.name, (context) => const SearchBarExample()), Component(TooltipExample.name, (context) => const TooltipExample()), Component(NavigationRailExample.name, (context) => const NavigationRailExample()), ]; diff --git a/example/lib/pages/components/search_bar_example.dart b/example/lib/pages/components/search_bar_example.dart new file mode 100644 index 00000000..693deea2 --- /dev/null +++ b/example/lib/pages/components/search_bar_example.dart @@ -0,0 +1,89 @@ +import 'package:flutter/material.dart'; +import 'package:zeta_example/widgets.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +class SearchBarExample extends StatefulWidget { + static const String name = 'SearchBar'; + + const SearchBarExample({Key? key}) : super(key: key); + + @override + State createState() => _SearchBarExampleState(); +} + +class _SearchBarExampleState extends State { + @override + Widget build(BuildContext context) { + return ExampleScaffold( + name: 'Search Bar', + child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('Rounded', style: ZetaTextStyles.titleMedium), + ), + Padding( + padding: const EdgeInsets.all(20), + child: ZetaSearchBar( + onChanged: (value) {}, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('Full', style: ZetaTextStyles.titleMedium), + ), + Padding( + padding: const EdgeInsets.all(20), + child: ZetaSearchBar( + shape: ZetaWidgetBorder.full, + onSpeechToText: () async => 'I wanted to say...', + ), + ), + Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('Sharp', style: ZetaTextStyles.titleMedium), + ), + Padding( + padding: const EdgeInsets.all(20), + child: ZetaSearchBar( + initialValue: 'Initial value', + shape: ZetaWidgetBorder.sharp, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('Disabled', style: ZetaTextStyles.titleMedium), + ), + Padding( + padding: const EdgeInsets.all(20), + child: ZetaSearchBar( + enabled: false, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('Medium', style: ZetaTextStyles.titleMedium), + ), + Padding( + padding: const EdgeInsets.all(20), + child: ZetaSearchBar( + size: ZetaWidgetSize.medium, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('Small', style: ZetaTextStyles.titleMedium), + ), + Padding( + padding: const EdgeInsets.all(20), + child: ZetaSearchBar( + size: ZetaWidgetSize.small, + ), + ), + ], + ), + ), + ); + } +} diff --git a/example/widgetbook/main.dart b/example/widgetbook/main.dart index 172069e5..0a7ffcce 100644 --- a/example/widgetbook/main.dart +++ b/example/widgetbook/main.dart @@ -26,6 +26,7 @@ import 'pages/components/password_input_widgetbook.dart'; import 'pages/components/phone_input_widgetbook.dart'; import 'pages/components/progress_widgetbook.dart'; import 'pages/components/radio_widgetbook.dart'; +import 'pages/components/search_bar_widgetbook.dart'; import 'pages/components/segmented_control_widgetbook.dart'; import 'pages/components/stepper_widgetbook.dart'; import 'pages/components/switch_widgetbook.dart'; @@ -133,6 +134,7 @@ class HotReload extends StatelessWidget { builder: (context) => stepperUseCase(context), ), WidgetbookUseCase(name: 'Dialog', builder: (context) => dialogUseCase(context)), + WidgetbookUseCase(name: 'Search Bar', builder: (context) => searchBarUseCase(context)), WidgetbookUseCase(name: 'Navigation Rail', builder: (context) => navigationRailUseCase(context)), WidgetbookUseCase(name: 'Tooltip', builder: (context) => tooltipUseCase(context)), ]..sort((a, b) => a.name.compareTo(b.name)), diff --git a/example/widgetbook/pages/components/search_bar_widgetbook.dart b/example/widgetbook/pages/components/search_bar_widgetbook.dart new file mode 100644 index 00000000..fb4b3b1c --- /dev/null +++ b/example/widgetbook/pages/components/search_bar_widgetbook.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +import '../../test/test_components.dart'; + +const List _items = [ + 'The quick...', + 'The quick brown...', + 'The quick brown fox...', + 'The quick brown fox jumped...', + 'The quick brown fox jumped into...', + 'The quick brown fox jumped into the hole...', +]; + +Widget searchBarUseCase(BuildContext context) { + List items = List.from(_items); + return WidgetbookTestWidget( + widget: StatefulBuilder( + builder: (context, setState) { + final hint = context.knobs.string( + label: 'Hint', + initialValue: 'Search', + ); + final enabled = context.knobs.boolean( + label: 'Enabled', + initialValue: true, + ); + final size = context.knobs.list( + label: 'Size', + options: ZetaWidgetSize.values, + labelBuilder: (size) => size.name, + ); + final shape = context.knobs.list( + label: 'Shape', + options: ZetaWidgetBorder.values, + labelBuilder: (shape) => shape.name, + ); + final showLeadingIcon = context.knobs.boolean( + label: 'Show leading icon', + initialValue: true, + ); + final showSpeechToText = context.knobs.boolean( + label: 'Show Speech-To-Text button', + initialValue: true, + ); + + return Padding( + padding: const EdgeInsets.all(ZetaSpacing.x5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ZetaSearchBar( + size: size, + shape: shape, + enabled: enabled, + hint: hint, + showLeadingIcon: showLeadingIcon, + showSpeechToText: showSpeechToText, + onChanged: (value) { + if (value == null) return; + setState( + () => items = _items + .where((item) => item.toLowerCase().contains( + value.toLowerCase(), + )) + .toList(), + ); + }, + onSpeechToText: () async => 'I wanted to say...', + ), + const SizedBox(height: ZetaSpacing.x5), + ...items.map((item) => Text(item)).toList(), + ], + ), + ); + }, + ), + ); +} diff --git a/lib/src/components/search_bar/search_bar.dart b/lib/src/components/search_bar/search_bar.dart new file mode 100644 index 00000000..514ae3f8 --- /dev/null +++ b/lib/src/components/search_bar/search_bar.dart @@ -0,0 +1,238 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import '../../../zeta_flutter.dart'; + +/// ZetaSearchBar provides input field for searching. +class ZetaSearchBar extends StatefulWidget { + /// Constructor for [ZetaSearchBar]. + const ZetaSearchBar({ + super.key, + this.size, + this.shape, + this.hint, + this.initialValue, + this.onChanged, + this.onSpeechToText, + this.enabled = true, + this.showLeadingIcon = true, + this.showSpeechToText = true, + }); + + /// Determines the size of the input field. + /// Default is `ZetaSearchBarSize.large` + final ZetaWidgetSize? size; + + /// Determines the shape of the input field. + /// Default is `ZetaSearchBarShape.rounded` + final ZetaWidgetBorder? shape; + + /// If provided, displays a hint inside the input field. + /// Default is `Search`. + final String? hint; + + /// The initial value. + final String? initialValue; + + /// A callback, which provides the entered text. + final void Function(String?)? onChanged; + + /// A callback, which is invoked when the microphone button is pressed. + final Future Function()? onSpeechToText; + + /// Determines if the input field should be enabled (default) or disabled. + final bool enabled; + + /// Determines if there should be a leading icon. + /// Default is `true`. + final bool showLeadingIcon; + + /// Determines if there should be a Speech-To-Text button. + /// Default is `true`. + final bool showSpeechToText; + + @override + State createState() => _ZetaSearchBarState(); + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(EnumProperty('size', size)) + ..add(EnumProperty('shape', shape)) + ..add(StringProperty('hint', hint)) + ..add(DiagnosticsProperty('enabled', enabled)) + ..add(ObjectFlagProperty.has('onChanged', onChanged)) + ..add(StringProperty('initialValue', initialValue)) + ..add(ObjectFlagProperty.has('onSpeechToText', onSpeechToText)) + ..add(DiagnosticsProperty('showLeadingIcon', showLeadingIcon)) + ..add(DiagnosticsProperty('showSpeechToText', showSpeechToText)); + } +} + +class _ZetaSearchBarState extends State { + late final TextEditingController _controller; + late ZetaWidgetSize _size; + late ZetaWidgetBorder _shape; + + @override + void initState() { + super.initState(); + _controller = TextEditingController(text: widget.initialValue ?? ''); + _size = widget.size ?? ZetaWidgetSize.large; + _shape = widget.shape ?? ZetaWidgetBorder.rounded; + } + + @override + void didUpdateWidget(ZetaSearchBar oldWidget) { + super.didUpdateWidget(oldWidget); + _size = widget.size ?? ZetaWidgetSize.large; + _shape = widget.shape ?? ZetaWidgetBorder.rounded; + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final zeta = Zeta.of(context); + final sharp = widget.shape == ZetaWidgetBorder.sharp; + final iconSize = _iconSize(_size); + + return TextFormField( + enabled: widget.enabled, + controller: _controller, + keyboardType: TextInputType.text, + onChanged: (value) => setState(() => widget.onChanged?.call(value)), + style: ZetaTextStyles.bodyMedium, + decoration: InputDecoration( + isDense: true, + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + vertical: _inputVerticalPadding(_size), + ), + hintText: widget.hint ?? 'Search', + hintStyle: ZetaTextStyles.bodyMedium.copyWith( + color: widget.enabled ? zeta.colors.textDefault : zeta.colors.cool.shade50, + ), + prefixIcon: widget.showLeadingIcon + ? Padding( + padding: const EdgeInsets.only(left: ZetaSpacing.x2_5, right: ZetaSpacing.xs), + child: Icon( + sharp ? ZetaIcons.search_sharp : ZetaIcons.search_round, + color: widget.enabled ? zeta.colors.cool.shade70 : zeta.colors.cool.shade50, + size: iconSize, + ), + ) + : null, + prefixIconConstraints: const BoxConstraints( + minHeight: ZetaSpacing.m, + minWidth: ZetaSpacing.m, + ), + suffixIcon: IntrinsicHeight( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (_controller.text.isNotEmpty && widget.enabled) ...[ + IconButton( + visualDensity: const VisualDensity( + horizontal: -4, + vertical: -4, + ), + onPressed: () { + setState(_controller.clear); + widget.onChanged?.call(''); + }, + icon: Icon( + sharp ? ZetaIcons.cancel_sharp : ZetaIcons.cancel_round, + color: zeta.colors.cool.shade70, + size: iconSize, + ), + ), + if (widget.showSpeechToText) + SizedBox( + height: iconSize, + child: VerticalDivider( + color: zeta.colors.cool.shade40, + width: 5, + thickness: 1, + ), + ), + ], + Padding( + padding: const EdgeInsets.only(right: ZetaSpacing.xxs), + child: widget.showSpeechToText + ? IconButton( + visualDensity: const VisualDensity( + horizontal: -4, + vertical: -4, + ), + onPressed: widget.onSpeechToText == null + ? null + : () async { + final text = await widget.onSpeechToText!.call(); + if (text != null) { + setState(() => _controller.text = text); + widget.onChanged?.call(text); + } + }, + icon: Icon( + sharp ? ZetaIcons.microphone_sharp : ZetaIcons.microphone_round, + size: iconSize, + ), + ) + : const SizedBox(), + ), + ], + ), + ), + suffixIconConstraints: const BoxConstraints( + minHeight: ZetaSpacing.m, + minWidth: ZetaSpacing.m, + ), + filled: widget.enabled ? null : true, + fillColor: widget.enabled ? null : zeta.colors.cool.shade30, + enabledBorder: _defaultInputBorder(zeta, shape: _shape), + focusedBorder: _focusedInputBorder(zeta, shape: _shape), + disabledBorder: _defaultInputBorder(zeta, shape: _shape), + ), + ); + } + + double _inputVerticalPadding(ZetaWidgetSize size) => switch (size) { + ZetaWidgetSize.large => ZetaSpacing.x3, + ZetaWidgetSize.medium => ZetaSpacing.x2, + ZetaWidgetSize.small => ZetaSpacing.x1, + }; + + double _iconSize(ZetaWidgetSize size) => switch (size) { + ZetaWidgetSize.large => ZetaSpacing.x6, + ZetaWidgetSize.medium => ZetaSpacing.x5, + ZetaWidgetSize.small => ZetaSpacing.x4, + }; + + OutlineInputBorder _defaultInputBorder( + Zeta zeta, { + required ZetaWidgetBorder shape, + }) => + OutlineInputBorder( + borderRadius: _borderRadius(shape), + borderSide: BorderSide(color: zeta.colors.cool.shade40), + ); + + OutlineInputBorder _focusedInputBorder( + Zeta zeta, { + required ZetaWidgetBorder shape, + }) => + OutlineInputBorder( + borderRadius: _borderRadius(shape), + borderSide: BorderSide(color: zeta.colors.blue.shade50), + ); + + BorderRadius _borderRadius(ZetaWidgetBorder shape) => switch (shape) { + ZetaWidgetBorder.rounded => ZetaRadius.minimal, + ZetaWidgetBorder.full => ZetaRadius.full, + _ => ZetaRadius.none, + }; +} diff --git a/lib/zeta_flutter.dart b/lib/zeta_flutter.dart index b722a8b3..f56ab17e 100644 --- a/lib/zeta_flutter.dart +++ b/lib/zeta_flutter.dart @@ -36,6 +36,7 @@ export 'src/components/phone_input/phone_input.dart'; export 'src/components/progress/progress_bar.dart'; export 'src/components/progress/progress_circle.dart'; export 'src/components/radio/radio.dart'; +export 'src/components/search_bar/search_bar.dart'; export 'src/components/segmented_control/segmented_control.dart'; export 'src/components/snack_bar/snack_bar.dart'; export 'src/components/stepper/stepper.dart'; From 26810ccb9fa2a97338aeec6b44a2b1f1bc71a548 Mon Sep 17 00:00:00 2001 From: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:51:30 +0300 Subject: [PATCH 15/15] Component phone input (#34) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * ZetaPhoneInput initial commit * complete ZetaPhoneInput; add flags * create phoneInputUseCase in Widgetbook * refactor phone input to use native alert dialog * don't use root navigator in widgetbook * pass parameter useRootNavigator * restore some missing countries in the list * countries search * add searchHint * fix comments * use ZetaSearchBar in CountriesDialog --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> --- .../phone_input/countries_dialog.dart | 36 ++++--------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/lib/src/components/phone_input/countries_dialog.dart b/lib/src/components/phone_input/countries_dialog.dart index 2f7876db..6539f878 100644 --- a/lib/src/components/phone_input/countries_dialog.dart +++ b/lib/src/components/phone_input/countries_dialog.dart @@ -117,7 +117,6 @@ class _CountriesList extends StatefulWidget { class _CountriesListState extends State<_CountriesList> { late final bool _enableSearch = widget.items.length > 20; - final _controller = TextEditingController(); List _items = []; @override @@ -126,7 +125,8 @@ class _CountriesListState extends State<_CountriesList> { _items = List.from(widget.items); } - void _search(String value) { + void _search(String? text) { + final value = text ?? ''; setState(() { _items = widget.items.where((item) { return item.value.name.toLowerCase().contains(value.toLowerCase()) || @@ -135,19 +135,6 @@ class _CountriesListState extends State<_CountriesList> { }); } - void _clearSearch() { - _controller.clear(); - setState(() { - _items = List.from(widget.items); - }); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - @override Widget build(BuildContext context) { final zeta = widget.zeta ?? Zeta.of(context); @@ -163,22 +150,11 @@ class _CountriesListState extends State<_CountriesList> { if (_enableSearch) Padding( padding: const EdgeInsets.only(bottom: ZetaSpacing.b), - child: TextField( - controller: _controller, + child: ZetaSearchBar( onChanged: _search, - decoration: InputDecoration( - hintText: widget.searchHint ?? 'Search by name or dial code', - prefixIcon: const Icon(ZetaIcons.search_round), - suffixIcon: _controller.text.isEmpty - ? null - : IconButton( - onPressed: _clearSearch, - icon: Icon( - ZetaIcons.cancel_round, - color: zeta.colors.cool.shade70, - ), - ), - ), + hint: widget.searchHint ?? 'Country or dial code', + shape: ZetaWidgetBorder.full, + showSpeechToText: false, ), ), if (_enableSearch)