From b3e018b333ac75f67c199be141d5a3c8e43cef91 Mon Sep 17 00:00:00 2001 From: gitadmin Date: Mon, 3 Nov 2025 11:29:32 +0530 Subject: [PATCH] edit profile changes --- lib/profile/fleet.dart | 760 ++++++++++++++++++----------------------- 1 file changed, 335 insertions(+), 425 deletions(-) diff --git a/lib/profile/fleet.dart b/lib/profile/fleet.dart index e8c6399..5377768 100644 --- a/lib/profile/fleet.dart +++ b/lib/profile/fleet.dart @@ -1,7 +1,10 @@ +import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:supplier_new/common/settings.dart'; +import 'employees.dart'; + class FleetStep1Page extends StatefulWidget { const FleetStep1Page({super.key}); @@ -10,41 +13,269 @@ class FleetStep1Page extends StatefulWidget { } class _FleetStep1PageState extends State { + bool isLoading = false; + List tankersList = []; + String search = ''; + + @override + void initState() { + super.initState(); + _fetchTankers(); + } + + Future _fetchTankers() async { + setState(() => isLoading = true); + try { + final response = await AppSettings.getTankers(); + final data = jsonDecode(response)['data'] as List; + if (!mounted) return; + setState(() { + tankersList = data; + isLoading = false; + }); + } catch (e) { + debugPrint("⚠️ Error fetching tankers: $e"); + setState(() => isLoading = false); + } + } + + void _openAddTankerSheet() { + showModalBottomSheet( + context: context, + isScrollControlled: true, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(24)), + ), + builder: (context) => const AddTankerForm(), + ).then((value) { + if (value == true) { + _fetchTankers(); + } + }); + } + + @override + Widget build(BuildContext context) { + final filtered = tankersList.where((it) { + final q = search.trim().toLowerCase(); + if (q.isEmpty) return true; + return it['tankerName'].toString().toLowerCase().contains(q); + }).toList(); + + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + backgroundColor: Colors.white, + surfaceTintColor: Colors.transparent, + elevation: 0, + title: const Text("Complete Profile"), + actions: [ + IconButton( + splashRadius: 20, + padding: EdgeInsets.zero, + icon: const Image( + image: AssetImage('images/calendar_appbar.png'), + width: 22, + height: 22, + ), + onPressed: () {}, + ), + IconButton( + splashRadius: 20, + padding: EdgeInsets.zero, + icon: Image.asset('images/notification_appbar.png', width: 22, height: 22), + onPressed: () {}, + ), + ], + ), + body: SafeArea( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Header + Padding( + padding: const EdgeInsets.fromLTRB(20, 10, 20, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Step 2/5", + style: fontTextStyle(16, Color(0xFFC3C4C4), FontWeight.w500)), + const SizedBox(height: 16), + Text("FLEET", + style: fontTextStyle(20, Color(0xFF515253), FontWeight.w600)), + const SizedBox(height: 8), + Image.asset('images/truck.png', width: 24, height: 24), + const SizedBox(height: 6), + Text( + "Details about your water tanker fleet", + style: fontTextStyle(14, Color(0xFF939495), FontWeight.w500), + ), + const SizedBox(height: 16), + ], + ), + ), + + // Tanker list + Expanded( + child: isLoading + ? const Center(child: CircularProgressIndicator()) + : tankersList.isEmpty + ? Center( + child: Text("No tankers added yet.", + style: fontTextStyle(14, Color(0xFF939495), FontWeight.w400), + ), + ) + : ListView.separated( + padding: const EdgeInsets.fromLTRB(8, 2, 8, 4), + itemCount: filtered.length, + separatorBuilder: (_, __) => const SizedBox(height: 8), + itemBuilder: (context, idx) { + final it = filtered[idx]; + return StatefulBuilder( + builder: (context, setLocalState) { + bool expanded = false; + + return StatefulBuilder( + builder: (context, setInner) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0), + decoration: BoxDecoration( + color: Color(0xFFF1F1F1), // background color + border: Border.all(color: Color(0xFFE5E5E5)), + borderRadius: BorderRadius.circular(29), + + ), + child: Column( + children: [ + ListTile( + dense: true, // 👈 makes tile shorter + contentPadding: EdgeInsets.zero, // 👈 removes default 16px + minVerticalPadding: 0, + title: Text( + it['tankerName'] ?? 'Unnamed', + style: fontTextStyle(14, Color(0xFF2D2E30), FontWeight.w600). copyWith(height: 0.1), + ), + trailing: IconButton( + icon: Image.asset( + expanded ? 'images/arrow-up.png' : 'images/downarrow.png', + width: 16, + height: 16, + ), + onPressed: () => setInner(() => expanded = !expanded), + ), + + + ), + if (expanded) + Align( + alignment: Alignment.centerLeft, + child: Container( + margin: const EdgeInsets.only(left: 10, right: 10, bottom: 6), + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), + decoration: BoxDecoration( + color: Color(0xFFFFFFFF), // 👈 white background + border: Border.all(color:Color(0xFFE5E5E5)), // light border + borderRadius: BorderRadius.circular(8), // smooth rounded edges + boxShadow: [ + BoxShadow(color: Color(0xFF2A2A2A).withOpacity(0.03), + blurRadius: 3, offset: const Offset(0, 1), + ), + ], + ), + child: Text( + "${it['typeofwater'] ?? ''} : ${it['capacity'] ?? ''} L", + textAlign: TextAlign.left, + style: fontTextStyle(12, Color(0xFF2A2A2A), FontWeight.w500, + ), + ), + ), + ), + + + + ], + ), + ); + }, + ); + }, + ); + }, + ), + + ), + + // Add + Continue buttons + Padding( + padding: const EdgeInsets.fromLTRB(16, 0, 16, 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + OutlinedButton.icon( + onPressed: _openAddTankerSheet, + icon: Image.asset('images/Add_icon.png', width: 16, height: 16), + label: Text( + "Add Tanker", + style: fontTextStyle(14, Color(0xFF646566), FontWeight.w600), + ), + ), + const SizedBox(height: 12), + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Color(0xFF8270DB), + foregroundColor: Color(0xFFFFFFFF), + padding: const EdgeInsets.symmetric(vertical: 14), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), + ), + onPressed: () { + Navigator.push(context, MaterialPageRoute(builder: (_) => const FleetEmployees())); + }, + child: Text( + "Continue", + style: fontTextStyle(14, Color(0xFFFFFFFF), FontWeight.w400), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} + +class AddTankerForm extends StatefulWidget { + const AddTankerForm({super.key}); + + @override + State createState() => _AddTankerFormState(); +} + +class _AddTankerFormState extends State { final _formKey = GlobalKey(); - // Controllers final _nameCtrl = TextEditingController(); - final _capacityCtrl = TextEditingController(); // hint-like + final _capacityCtrl = TextEditingController(); final _plateCtrl = TextEditingController(); final _mfgYearCtrl = TextEditingController(); final _insExpiryCtrl = TextEditingController(); - // Dropdowns / selections + String? selectedType; + String? selectedTypeOfWater; + final List tankerTypes = [ "Rigid Truck", "Trailer", "Mini Tanker", "Hydraulic", ]; - String? selectedType; final List typeOfWater = [ "Bore Water", "Drinking Water", ]; - String? selectedTypeOfWater; - final List featureOptions = [ - "GPS", - "Stainless Steel", - "Partitioned", - "Food Grade", - "Top Loading", - "Bottom Loading", - ]; - final Set selectedFeatures = {}; - - // Helpers Future _pickInsuranceDate() async { final now = DateTime.now(); final date = await showDatePicker( @@ -56,207 +287,74 @@ class _FleetStep1PageState extends State { ); if (date != null) { _insExpiryCtrl.text = - "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}"; + "${date.day.toString().padLeft(2, '0')}-${date.month.toString().padLeft(2, '0')}-${date.year}"; setState(() {}); } } - String? _required(String? v, {String field = "This field"}) { - if (v == null || v.trim().isEmpty) return "$field is required"; - return null; - } - - @override - void dispose() { - _nameCtrl.dispose(); - _capacityCtrl.dispose(); - _plateCtrl.dispose(); - _mfgYearCtrl.dispose(); - _insExpiryCtrl.dispose(); - super.dispose(); - } - - // Store multiple tanker entries - final List> _tankers = []; - - Map _buildPayload() => { - "tanker_name": _nameCtrl.text.trim(), - "capacity": _capacityCtrl.text.trim(), - "type": selectedType, - "features": selectedFeatures.toList(), - "license_plate": _plateCtrl.text.trim(), - "manufacturing_year": _mfgYearCtrl.text.trim(), - "insurance_expiry": _insExpiryCtrl.text.trim(), - }; - - void _clearForm() { - _nameCtrl.clear(); - _capacityCtrl.text = "10,000"; - _plateCtrl.text = "AB 05 H 4948"; - _mfgYearCtrl.clear(); - _insExpiryCtrl.clear(); - selectedType = null; - selectedFeatures.clear(); - setState(() {}); - } - - void _addTanker() async{ - final ok = _formKey.currentState?.validate() ?? false; - setState(() {}); // in case you show chip validation below labels - var payload = new Map(); - payload["tankerName"] = _nameCtrl.text.toString(); - payload["capacity"] = _capacityCtrl.text.toString(); - payload["typeofwater"] =selectedTypeOfWater.toString(); - payload["supplier_address"] = AppSettings.userAddress; - payload["supplier_name"] = AppSettings.userName; - payload["phoneNumber"] = AppSettings.phoneNumber; - payload["tanker_type"] =selectedType; - payload["license_plate"] =_plateCtrl.text.trim(); - payload["manufacturing_year"] = _mfgYearCtrl.text.trim(); - payload["insurance_exp_date"] = _insExpiryCtrl.text.trim(); - + Future _addTanker() async { + if (!(_formKey.currentState?.validate() ?? false)) return; + + var payload = { + "tankerName": _nameCtrl.text.trim(), + "capacity": _capacityCtrl.text.trim(), + "typeofwater": selectedTypeOfWater, + "supplier_address": AppSettings.userAddress, + "supplier_name": AppSettings.userName, + "phoneNumber": AppSettings.phoneNumber, + "tanker_type": selectedType, + "license_plate": _plateCtrl.text.trim(), + "manufacturing_year": _mfgYearCtrl.text.trim(), + "insurance_exp_date": _insExpiryCtrl.text.trim(), + }; bool tankStatus = await AppSettings.addTankers(payload); - try { - if (tankStatus) { - AppSettings.longSuccessToast("Tanker Created Successfully"); - _nameCtrl.text = ''; - _capacityCtrl.text = ''; - Navigator.pop(context,true); - - } - else { - AppSettings.longFailedToast("Tanker Creation failed"); - } - } catch (exception) { - print(exception); + if (tankStatus) { + AppSettings.longSuccessToast("Tanker Created Successfully"); + Navigator.pop(context, true); + } else { + AppSettings.longFailedToast("Tanker Creation Failed"); } - _clearForm(); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text("Tanker added (${_tankers.length})")), - ); } @override Widget build(BuildContext context) { - final theme = Theme.of(context); - - return Scaffold( - backgroundColor: Colors.white, - appBar: AppBar( - backgroundColor: Colors.white, - title: const Text("Complete Profile"), - actions: [ - Padding(padding: EdgeInsets.fromLTRB(10,10,0,10), - child: IconButton( - icon: Image( - image: AssetImage('images/calendar_appbar.png') - - ), - onPressed: (){ - - }, - ), - ), - - Padding(padding: EdgeInsets.fromLTRB(0,10,10,10), - child: IconButton( - icon: Image.asset( - 'images/notification_appbar.png', // Example URL image - ), - onPressed: (){ + return Padding( + padding: MediaQuery.of(context).viewInsets.add(const EdgeInsets.all(20)), - }, - ), - ) - ], - ), - body: SafeArea( + child: SingleChildScrollView( child: Form( key: _formKey, - child: ListView( - padding: const EdgeInsets.fromLTRB(20, 10, 20, 24), + child: Column( + mainAxisSize: MainAxisSize.min, children: [ - // Step indicator - Text( - "Step 1/5", - style: - fontTextStyle(16, const Color(0xFFC3C4C4), FontWeight.w500), - ), + Text("Add New Tanker", + style: fontTextStyle(18, Color(0xFF2D2E30), FontWeight.w600)), const SizedBox(height: 16), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "FLEET", - style: fontTextStyle( - 20, const Color(0xFF515253), FontWeight.w600), - ), - const SizedBox(height: 8), - Container( - width: 24, - height: 24, - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage('images/truck.png'), - fit: BoxFit.contain, - ), - ), - ), - ], - ), - - const SizedBox(height: 6), - Text( - "Details about your water tanker fleet", - style: - fontTextStyle(14, const Color(0xFF939495), FontWeight.w500), - ), - const SizedBox(height: 16), - - _SectionHeaderBar( - title: "WATER TANKER #1", - icon: Image.asset('images/arrow-up.png', width: 16, height: 16), - radius: 20, - ), - const SizedBox(height: 12), _LabeledField( label: "Tanker Name *", child: TextFormField( controller: _nameCtrl, - validator: (v) => _required(v, field: "Tanker Name"), - decoration: const InputDecoration( - hintText: "Enter Tanker Name", - border: OutlineInputBorder(), - isDense: true, - ), - textInputAction: TextInputAction.next, + validator: (v) => v == null || v.isEmpty ? "Required" : null, + decoration: + const InputDecoration(border: OutlineInputBorder(), isDense: true), ), ), - _LabeledField( - label: "Tanker Capacity (in L) *", + label: "Capacity (in L) *", child: TextFormField( controller: _capacityCtrl, - validator: (v) => _required(v, field: "Tanker Capacity"), - decoration: InputDecoration( - hintText: "10,000 L", - hintStyle: fontTextStyle( - 14, const Color(0xFF939495), FontWeight.w400), - border: const OutlineInputBorder(), - isDense: true, - ), + validator: (v) => v == null || v.isEmpty ? "Required" : null, keyboardType: TextInputType.number, inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp(r'[0-9,]')), + FilteringTextInputFormatter.allow(RegExp(r'[0-9,]')) ], - textInputAction: TextInputAction.next, + decoration: + const InputDecoration(border: OutlineInputBorder(), isDense: true), ), ), - _LabeledField( label: "Tanker Type *", child: DropdownButtonFormField( @@ -265,204 +363,65 @@ class _FleetStep1PageState extends State { .map((t) => DropdownMenuItem(value: t, child: Text(t))) .toList(), onChanged: (v) => setState(() => selectedType = v), - validator: (v) => - v == null || v.isEmpty ? "Tanker Type is required" : null, - isExpanded: true, - alignment: Alignment.centerLeft, - hint: Text( - "Select Type", - style: fontTextStyle( - 14, const Color(0xFF939495), FontWeight.w400), - ), - - icon: Image.asset('images/downarrow.png', - width: 16, height: 16), - - decoration: const InputDecoration( - border: OutlineInputBorder(), - isDense: false, - contentPadding: - EdgeInsets.symmetric(horizontal: 12, vertical: 14), - ), + validator: (v) => v == null ? "Required" : null, + decoration: + const InputDecoration(border: OutlineInputBorder(), isDense: true), ), ), - _LabeledField( - label: "Type of water *", + label: "Type of Water *", child: DropdownButtonFormField( value: selectedTypeOfWater, items: typeOfWater .map((t) => DropdownMenuItem(value: t, child: Text(t))) .toList(), onChanged: (v) => setState(() => selectedTypeOfWater = v), - validator: (v) => - v == null || v.isEmpty ? "Type of water is required" : null, - isExpanded: true, - alignment: Alignment.centerLeft, - - // <-- Hint: left-aligned, vertically centered by padding - hint: Text( - "Select type of water", - style: fontTextStyle( - 14, const Color(0xFF939495), FontWeight.w400), - ), - - icon: Image.asset('images/downarrow.png', - width: 16, height: 16), - - decoration: const InputDecoration( - border: OutlineInputBorder(), - isDense: false, // keep some height - contentPadding: - EdgeInsets.symmetric(horizontal: 12, vertical: 14), - ), + validator: (v) => v == null ? "Required" : null, + decoration: + const InputDecoration(border: OutlineInputBorder(), isDense: true), ), ), - _LabeledField( label: "License Plate *", child: TextFormField( controller: _plateCtrl, - validator: (v) => _required(v, field: "License Plate"), - decoration: InputDecoration( - hintText: "AB 05 H 4948", - hintStyle: fontTextStyle( - 14, const Color(0xFF939495), FontWeight.w400), - border: const OutlineInputBorder(), - isDense: true, - ), + validator: (v) => v == null || v.isEmpty ? "Required" : null, textCapitalization: TextCapitalization.characters, - textInputAction: TextInputAction.next, + decoration: + const InputDecoration(border: OutlineInputBorder(), isDense: true), ), ), - _LabeledField( - label: "Manufacturing Year (opt)", + label: "Manufacturing Year", child: TextFormField( controller: _mfgYearCtrl, - decoration: InputDecoration( - hintText: "YYYY", - hintStyle: fontTextStyle( - 14, const Color(0xFF939495), FontWeight.w400), - border: const OutlineInputBorder(), - isDense: true, - ), keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, - LengthLimitingTextInputFormatter(4), + LengthLimitingTextInputFormatter(4) ], - textInputAction: TextInputAction.next, + decoration: + const InputDecoration(border: OutlineInputBorder(), isDense: true), ), ), - _LabeledField( - label: "Insurance Expiry Date (opt)", + label: "Insurance Expiry Date", child: TextFormField( controller: _insExpiryCtrl, readOnly: true, - decoration: InputDecoration( - hintText: "DD-MM-YYYY", - hintStyle: fontTextStyle( - 14, const Color(0xFF939495), FontWeight.w400), - border: const OutlineInputBorder(), - isDense: true, - ), onTap: _pickInsuranceDate, + decoration: + const InputDecoration(border: OutlineInputBorder(), isDense: true), ), ), - - const SizedBox(height: 20), - // Save / Continue - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - SizedBox( - width: double.infinity, - child: OutlinedButton.icon( - onPressed: _addTanker, - icon: Image.asset('images/Add_icon.png', - width: 16, height: 16), - // pulsing image - label: Text( - "Add Tanker", - style: fontTextStyle( - 14, const Color(0xFF646566), FontWeight.w600), - ), - ), - ), - - const SizedBox(height: 12), - - // Continue (primary) - /* SizedBox( - width: double.infinity, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF8270DB), // purple bg - foregroundColor: Colors.white, // ripple/icon/text color - padding: const EdgeInsets.symmetric(vertical: 14), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(24)), - ), - onPressed: () async{ - - if (_nameCtrl.text != '' && - _capacityCtrl.text != '' && - _plateCtrl.text != '') { - - var payload = new Map(); - payload["tankerName"] = _nameCtrl.text.toString(); - payload["capacity"] = _capacityCtrl.text.toString(); - payload["typeofwater"] =selectedTypeOfWater.toString(); - payload["supplier_address"] = AppSettings.userAddress; - payload["supplier_name"] = AppSettings.userName; - - bool tankStatus = await AppSettings.addTankers(payload); - - try { - if (tankStatus) { - AppSettings.longSuccessToast( - "Tanker Created Successfully"); - _nameCtrl.text = ''; - //tankerPhoneNumberController.text = ''; - _capacityCtrl.text = ''; - //tankerAlternativePhoneNumberController.text=''; - Navigator.pop(context); - *//* await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => TankersView()), - );*//* - - } - else { - AppSettings.longFailedToast("Tanker Creation failed"); - } - } catch (exception) { - print(exception); - } - } else { - AppSettings.longFailedToast("Please enter valid details"); - } - - _nameCtrl.clear(); - _capacityCtrl.text = "10,000"; - _plateCtrl.text = "AB 05 H 4948"; - _mfgYearCtrl.clear(); - _insExpiryCtrl.clear(); - selectedType = null; - selectedFeatures.clear(); - }, - child: Text( - "Continue", - style: fontTextStyle( - 14, Colors.white, FontWeight.w400), // white text - ), - ), - )*/ - ], - ) + const SizedBox(height: 16), + ElevatedButton( + onPressed: _addTanker, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF0D3771), + foregroundColor: Colors.white), + child: const Text("Add Tanker"), + ), ], ), ), @@ -471,96 +430,47 @@ class _FleetStep1PageState extends State { } } - -class _SectionHeaderBar extends StatelessWidget { - final String title; - final Widget? icon; - final Color backgroundColor; - final Color borderColor; - final double radius; - - const _SectionHeaderBar({ - required this.title, - this.icon, - this.backgroundColor = const Color(0xFFEEEEEE), - this.borderColor = const Color(0xFFE5E7EB), - this.radius = 8, - Key? key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - color: backgroundColor, - border: Border.all(color: borderColor, width: 1), - borderRadius: BorderRadius.circular(radius), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.04), - blurRadius: 6, - offset: const Offset(0, 2), - ), - ], - ), - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), - child: Row( - children: [ - Expanded( - child: Text( - title, - style: - fontTextStyle(12, const Color(0xFF2D2E30), FontWeight.w600), - ), - ), - if (icon != null) icon!, - ], - ), - ); - } -} - class _LabeledField extends StatelessWidget { final String label; final Widget child; - final String? Function()? validator; - const _LabeledField({ - required this.label, - required this.child, - this.validator, - }); + const _LabeledField({required this.label, required this.child}); @override Widget build(BuildContext context) { - final labelStyle = Theme.of(context) - .textTheme - .bodyMedium - ?.copyWith(color: Colors.grey.shade800); - - final errorText = validator != null ? validator!() : null; - return Padding( - padding: const EdgeInsets.only(bottom: 14.0), + padding: const EdgeInsets.only(bottom: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(label, - style: - fontTextStyle(12, const Color(0xFF515253), FontWeight.w600)), - const SizedBox(height: 6), + Text(label, style: fontTextStyle(12, Color(0xFF515253), FontWeight.w600)), + SizedBox(height: 6), child, - if (errorText != null) - Padding( - padding: const EdgeInsets.only(top: 6), - child: Text( - errorText, - style: - fontTextStyle(14, const Color(0xFF939495), FontWeight.w400), - ), - ), ], ), ); } } +Widget _detailRow(String label, dynamic value) { + return Padding( + padding: const EdgeInsets.only(bottom: 4), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "$label ", + style: fontTextStyle(12, Color(0xFF515253), FontWeight.w600), + ), + Expanded( + child: Text( + value == null || value.toString().isEmpty + ? "-" + : value.toString(), + style: + fontTextStyle(12, Color(0xFF646566), FontWeight.w400), + ), + ), + ], + ), + ); +}