|
|
|
|
@ -6,6 +6,7 @@ import 'package:mc_common_app/extensions/int_extensions.dart';
|
|
|
|
|
import 'package:mc_common_app/extensions/string_extensions.dart';
|
|
|
|
|
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
|
|
|
|
import 'package:mc_common_app/models/user_models/register_user.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/enums.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/navigator.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/user_view_model.dart';
|
|
|
|
|
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
|
|
|
|
|
@ -27,10 +28,7 @@ class CompleteProfilePage extends StatefulWidget {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _CompleteProfilePageState extends State<CompleteProfilePage> {
|
|
|
|
|
String? firstName = "",
|
|
|
|
|
lastName = "",
|
|
|
|
|
email = "",
|
|
|
|
|
confirmPassword = "";
|
|
|
|
|
String? firstName = "", lastName = "", email = "", confirmPassword = "", companyName = "";
|
|
|
|
|
late String password = "";
|
|
|
|
|
bool isChecked = false;
|
|
|
|
|
DropValue? city;
|
|
|
|
|
@ -41,231 +39,234 @@ class _CompleteProfilePageState extends State<CompleteProfilePage> {
|
|
|
|
|
super.initState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
context.read<UserVM>().getAllCitiesForUser(AppState().getUserRegisterCountrySelection.id);
|
|
|
|
|
return Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) {
|
|
|
|
|
userVM.getAllCitiesForUser(AppState().getUserRegisterCountrySelection.id);
|
|
|
|
|
return Scaffold(
|
|
|
|
|
appBar: CustomAppBar(
|
|
|
|
|
isRemoveBackButton: widget.user.data!.roleId == 7 ? false : true,
|
|
|
|
|
title: widget.user.data!.roleId == 7 ? "" : LocaleKeys.signUp.tr(),
|
|
|
|
|
),
|
|
|
|
|
body: SizedBox(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
height: double.infinity,
|
|
|
|
|
child: SingleChildScrollView(
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.all(20),
|
|
|
|
|
child: Column(
|
|
|
|
|
children: [
|
|
|
|
|
6.height,
|
|
|
|
|
LocaleKeys.completeProfile.tr().toText(
|
|
|
|
|
height: 23 / 24,
|
|
|
|
|
fontSize: 24,
|
|
|
|
|
letterSpacing: -1.44,
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
|
|
|
|
child: LocaleKeys.profileMsg.tr().toText(
|
|
|
|
|
color: MyColors.lightTextColor,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
appBar: CustomAppBar(
|
|
|
|
|
isRemoveBackButton: widget.user.data!.roleId == 7 ? false : true,
|
|
|
|
|
title: widget.user.data!.roleId == 7 ? "" : LocaleKeys.signUp.tr(),
|
|
|
|
|
),
|
|
|
|
|
body: SizedBox(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
height: double.infinity,
|
|
|
|
|
child: SingleChildScrollView(
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.all(20),
|
|
|
|
|
child: Column(
|
|
|
|
|
children: [
|
|
|
|
|
6.height,
|
|
|
|
|
LocaleKeys.completeProfile.tr().toText(
|
|
|
|
|
height: 23 / 24,
|
|
|
|
|
letterSpacing: -0.48,
|
|
|
|
|
fontSize: 24,
|
|
|
|
|
letterSpacing: -1.44,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.firstName.tr(),
|
|
|
|
|
value: firstName,
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
firstName = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
|
|
|
|
child: LocaleKeys.profileMsg.tr().toText(
|
|
|
|
|
color: MyColors.lightTextColor,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
height: 23 / 24,
|
|
|
|
|
letterSpacing: -0.48,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.firstName.tr(),
|
|
|
|
|
value: firstName,
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
firstName = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.surname.tr(),
|
|
|
|
|
value: lastName,
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
lastName = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
if (AppState().currentAppType == AppType.provider) ...[
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.surname.tr(),
|
|
|
|
|
value: lastName,
|
|
|
|
|
hint: LocaleKeys.companyName.tr(),
|
|
|
|
|
value: companyName,
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
lastName = v;
|
|
|
|
|
companyName = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
Container(
|
|
|
|
|
padding: const EdgeInsets.only(right: 0, left: 0, top: 0, bottom: 0),
|
|
|
|
|
child: Builder(builder: (context) {
|
|
|
|
|
List<DropValue> userGender = [];
|
|
|
|
|
userGender.add(DropValue(1.toInt(), "${LocaleKeys.userMale.tr()}", "", isEnabled: true));
|
|
|
|
|
userGender.add(DropValue(2.toInt(), "${LocaleKeys.userFemale.tr()}", "", isEnabled: true));
|
|
|
|
|
// for (var element in userVM.userCities!.data!) {
|
|
|
|
|
// if (AppState().getUser.data != null) {
|
|
|
|
|
// if (AppState().getUser.data!.userInfo!.cityId == element.id) {
|
|
|
|
|
// city = DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", "");
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
return DropdownField(
|
|
|
|
|
(DropValue value) {
|
|
|
|
|
gender = value;
|
|
|
|
|
setState(() {});
|
|
|
|
|
},
|
|
|
|
|
list: userGender,
|
|
|
|
|
dropdownValue: gender != null && gender != -1 ? DropValue(gender!.id, gender!.value, "") : null,
|
|
|
|
|
hint: gender != null && gender != -1 ? gender!.value : "${LocaleKeys.userGender.tr()} *",
|
|
|
|
|
// errorValue: adVM.vehicleCountryId.errorValue,
|
|
|
|
|
);
|
|
|
|
|
})),
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.email.tr(),
|
|
|
|
|
value: email,
|
|
|
|
|
// isButtonEnable: email!.length > 0 ? true : false,
|
|
|
|
|
buttonTitle: LocaleKeys.verify.tr(),
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
email = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
userVM.userCities != null
|
|
|
|
|
? Container(
|
|
|
|
|
padding: const EdgeInsets.only(right: 0, left: 0, top: 0, bottom: 0),
|
|
|
|
|
child: Builder(builder: (context) {
|
|
|
|
|
List<DropValue> userCityDrop = [];
|
|
|
|
|
for (var element in userVM.userCities!.data!) {
|
|
|
|
|
if (AppState().getUser.data != null) {
|
|
|
|
|
if (AppState().getUser.data!.userInfo!.cityId == element.id) {
|
|
|
|
|
city = DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", "");
|
|
|
|
|
],
|
|
|
|
|
12.height,
|
|
|
|
|
Container(
|
|
|
|
|
padding: const EdgeInsets.only(right: 0, left: 0, top: 0, bottom: 0),
|
|
|
|
|
child: Builder(builder: (context) {
|
|
|
|
|
List<DropValue> userGender = [];
|
|
|
|
|
userGender.add(DropValue(1.toInt(), "${LocaleKeys.userMale.tr()}", "", isEnabled: true));
|
|
|
|
|
userGender.add(DropValue(2.toInt(), "${LocaleKeys.userFemale.tr()}", "", isEnabled: true));
|
|
|
|
|
// for (var element in userVM.userCities!.data!) {
|
|
|
|
|
// if (AppState().getUser.data != null) {
|
|
|
|
|
// if (AppState().getUser.data!.userInfo!.cityId == element.id) {
|
|
|
|
|
// city = DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", "");
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
return DropdownField(
|
|
|
|
|
(DropValue value) {
|
|
|
|
|
gender = value;
|
|
|
|
|
setState(() {});
|
|
|
|
|
},
|
|
|
|
|
list: userGender,
|
|
|
|
|
dropdownValue: gender != null && gender != -1 ? DropValue(gender!.id, gender!.value, "") : null,
|
|
|
|
|
hint: gender != null && gender != -1 ? gender!.value : "${LocaleKeys.userGender.tr()} *",
|
|
|
|
|
// errorValue: adVM.vehicleCountryId.errorValue,
|
|
|
|
|
);
|
|
|
|
|
})),
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.email.tr(),
|
|
|
|
|
value: email,
|
|
|
|
|
// isButtonEnable: email!.length > 0 ? true : false,
|
|
|
|
|
buttonTitle: LocaleKeys.verify.tr(),
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
email = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
userVM.userCities != null
|
|
|
|
|
? Container(
|
|
|
|
|
padding: const EdgeInsets.only(right: 0, left: 0, top: 0, bottom: 0),
|
|
|
|
|
child: Builder(builder: (context) {
|
|
|
|
|
List<DropValue> userCityDrop = [];
|
|
|
|
|
for (var element in userVM.userCities!.data!) {
|
|
|
|
|
if (AppState().getUser.data != null) {
|
|
|
|
|
if (AppState().getUser.data!.userInfo!.cityId == element.id) {
|
|
|
|
|
city = DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", "");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
userCityDrop.add(DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", ""));
|
|
|
|
|
}
|
|
|
|
|
userCityDrop.add(DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", ""));
|
|
|
|
|
}
|
|
|
|
|
return DropdownField(
|
|
|
|
|
(DropValue value) {
|
|
|
|
|
city = value;
|
|
|
|
|
setState(() {});
|
|
|
|
|
},
|
|
|
|
|
list: userCityDrop,
|
|
|
|
|
dropdownValue: city != null && city != -1 ? DropValue(city!.id, city!.value, "") : null,
|
|
|
|
|
hint: city != null && city != -1 ? city!.value : "${LocaleKeys.city.tr()} *",
|
|
|
|
|
// errorValue: adVM.vehicleCountryId.errorValue,
|
|
|
|
|
);
|
|
|
|
|
}))
|
|
|
|
|
: SizedBox(),
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.createPass.tr(),
|
|
|
|
|
isPasswordEnabled: true,
|
|
|
|
|
maxLines: 1,
|
|
|
|
|
value: password,
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
password = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.confirmPass.tr(),
|
|
|
|
|
isPasswordEnabled: true,
|
|
|
|
|
maxLines: 1,
|
|
|
|
|
value: confirmPassword,
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
confirmPassword = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
50.height,
|
|
|
|
|
Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
|
|
children: [
|
|
|
|
|
Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) {
|
|
|
|
|
return Checkbox(
|
|
|
|
|
value: userVM.completeProfilePageCheckbox,
|
|
|
|
|
activeColor: MyColors.darkPrimaryColor,
|
|
|
|
|
onChanged: (value) {
|
|
|
|
|
userVM.updateCompleteProfilePageCheckbox(value!);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
return DropdownField(
|
|
|
|
|
(DropValue value) {
|
|
|
|
|
city = value;
|
|
|
|
|
setState(() {});
|
|
|
|
|
},
|
|
|
|
|
list: userCityDrop,
|
|
|
|
|
dropdownValue: city != null && city != -1 ? DropValue(city!.id, city!.value, "") : null,
|
|
|
|
|
hint: city != null && city != -1 ? city!.value : "${LocaleKeys.city.tr()} *",
|
|
|
|
|
// errorValue: adVM.vehicleCountryId.errorValue,
|
|
|
|
|
);
|
|
|
|
|
}))
|
|
|
|
|
: SizedBox(),
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.createPass.tr(),
|
|
|
|
|
isPasswordEnabled: true,
|
|
|
|
|
maxLines: 1,
|
|
|
|
|
value: password,
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
password = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
TxtField(
|
|
|
|
|
hint: LocaleKeys.confirmPass.tr(),
|
|
|
|
|
isPasswordEnabled: true,
|
|
|
|
|
maxLines: 1,
|
|
|
|
|
value: confirmPassword,
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
confirmPassword = v;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
50.height,
|
|
|
|
|
Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
|
|
children: [
|
|
|
|
|
Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) {
|
|
|
|
|
return Checkbox(
|
|
|
|
|
value: userVM.completeProfilePageCheckbox,
|
|
|
|
|
activeColor: MyColors.darkPrimaryColor,
|
|
|
|
|
onChanged: (value) {
|
|
|
|
|
userVM.updateCompleteProfilePageCheckbox(value!);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Text.rich(
|
|
|
|
|
TextSpan(
|
|
|
|
|
children: [
|
|
|
|
|
TextSpan(
|
|
|
|
|
text: LocaleKeys.termsOfService.tr(),
|
|
|
|
|
style: const TextStyle(fontSize: 12, fontWeight: MyFonts.Medium),
|
|
|
|
|
),
|
|
|
|
|
TextSpan(
|
|
|
|
|
text: " ${LocaleKeys.terms.tr()}",
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
decoration: TextDecoration.underline,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
color: MyColors.darkPrimaryColor,
|
|
|
|
|
fontWeight: MyFonts.Bold,
|
|
|
|
|
))
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
).onPress(() {
|
|
|
|
|
navigateWithName(context, AppRoutes.settingOptionsTermsAndConditions);
|
|
|
|
|
}),
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Text.rich(
|
|
|
|
|
TextSpan(
|
|
|
|
|
children: [
|
|
|
|
|
TextSpan(
|
|
|
|
|
text: LocaleKeys.termsOfService.tr(),
|
|
|
|
|
style: const TextStyle(fontSize: 12, fontWeight: MyFonts.Medium),
|
|
|
|
|
),
|
|
|
|
|
TextSpan(
|
|
|
|
|
text: " ${LocaleKeys.terms.tr()}",
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
decoration: TextDecoration.underline,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
color: MyColors.darkPrimaryColor,
|
|
|
|
|
fontWeight: MyFonts.Bold,
|
|
|
|
|
))
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
).onPress(() {
|
|
|
|
|
navigateWithName(context, AppRoutes.settingOptionsTermsAndConditions);
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
// Column(
|
|
|
|
|
// children: [
|
|
|
|
|
// LocaleKeys.termsOfService.tr().toText(fontSize: 12),
|
|
|
|
|
// LocaleKeys.terms.tr().toText(fontSize: 12, color: MyColors.darkPrimaryColor),
|
|
|
|
|
// ],
|
|
|
|
|
// ),
|
|
|
|
|
// Theme(
|
|
|
|
|
// data: ThemeData(unselectedWidgetColor: Colors.transparent),
|
|
|
|
|
// child: Checkbox(
|
|
|
|
|
// value: false,
|
|
|
|
|
// onChanged: (_) {},
|
|
|
|
|
// ),
|
|
|
|
|
// )
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
16.height,
|
|
|
|
|
Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) {
|
|
|
|
|
return ShowFillButton(
|
|
|
|
|
title: LocaleKeys.save.tr(),
|
|
|
|
|
maxWidth: double.infinity,
|
|
|
|
|
isDisabled: !userVM.completeProfilePageCheckbox,
|
|
|
|
|
onPressed: () {
|
|
|
|
|
if (!userVM.completeProfilePageCheckbox) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
bool validateStatus = userVM.dataValidation(password: password,
|
|
|
|
|
firstName: firstName,
|
|
|
|
|
lastName: lastName,
|
|
|
|
|
email: email,
|
|
|
|
|
city: city,
|
|
|
|
|
gender: gender);
|
|
|
|
|
if (validateStatus) {
|
|
|
|
|
userVM.performCompleteProfile(
|
|
|
|
|
context,
|
|
|
|
|
password: password,
|
|
|
|
|
confirmPassword: confirmPassword!,
|
|
|
|
|
firstName: firstName!,
|
|
|
|
|
lastName: lastName!,
|
|
|
|
|
email: email!,
|
|
|
|
|
userId: widget.user.data!.userId ?? "",
|
|
|
|
|
isNeedToPassToken: widget.user.data!.isNeedToPassToken,
|
|
|
|
|
cityID: city!.id.toString(),
|
|
|
|
|
genderID: gender!.id.toString(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}),
|
|
|
|
|
16.height,
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
// Column(
|
|
|
|
|
// children: [
|
|
|
|
|
// LocaleKeys.termsOfService.tr().toText(fontSize: 12),
|
|
|
|
|
// LocaleKeys.terms.tr().toText(fontSize: 12, color: MyColors.darkPrimaryColor),
|
|
|
|
|
// ],
|
|
|
|
|
// ),
|
|
|
|
|
// Theme(
|
|
|
|
|
// data: ThemeData(unselectedWidgetColor: Colors.transparent),
|
|
|
|
|
// child: Checkbox(
|
|
|
|
|
// value: false,
|
|
|
|
|
// onChanged: (_) {},
|
|
|
|
|
// ),
|
|
|
|
|
// )
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
16.height,
|
|
|
|
|
Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) {
|
|
|
|
|
return ShowFillButton(
|
|
|
|
|
title: LocaleKeys.save.tr(),
|
|
|
|
|
maxWidth: double.infinity,
|
|
|
|
|
isDisabled: !userVM.completeProfilePageCheckbox,
|
|
|
|
|
onPressed: () {
|
|
|
|
|
if (!userVM.completeProfilePageCheckbox) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
bool validateStatus = userVM.dataValidation(password: password, firstName: firstName, lastName: lastName, companyName: companyName, email: email, city: city, gender: gender);
|
|
|
|
|
if (validateStatus) {
|
|
|
|
|
userVM.performCompleteProfile(
|
|
|
|
|
context,
|
|
|
|
|
password: password,
|
|
|
|
|
confirmPassword: confirmPassword!,
|
|
|
|
|
firstName: firstName!,
|
|
|
|
|
lastName: lastName!,
|
|
|
|
|
companyName: companyName!,
|
|
|
|
|
email: email!,
|
|
|
|
|
userId: widget.user.data!.userId ?? "",
|
|
|
|
|
isNeedToPassToken: widget.user.data!.isNeedToPassToken,
|
|
|
|
|
cityID: city!.id.toString(),
|
|
|
|
|
genderID: gender!.id.toString(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}),
|
|
|
|
|
16.height,
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|