Commit 59f975ac by Ramesh Babu Puvvadi

added Stock, Sale and View List

parent 25d9c72d
......@@ -153,11 +153,10 @@ class Constants {
static showLoader(BuildContext ctx) {
showDialog(
context: ctx,
builder: (context) {
return const Center(child: CircularProgressIndicator());
}
);
context: ctx,
builder: (context) {
return const Center(child: CircularProgressIndicator());
});
}
static Future<void> dismissAlertDialog1(BuildContext context) async {
......@@ -232,8 +231,7 @@ class Constants {
child: const Text("Cancel"),
onPressed: () {
Navigator.of(context).pop();
}
);
});
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(message),
......@@ -255,6 +253,35 @@ class Constants {
return dropdownItemHeight;
}
static Showindicator(BuildContext context, String loadertext) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const CircularProgressIndicator(
color: Color.fromARGB(255, 69, 66, 121),
),
const SizedBox(height: 16), // Add some spacing
Text(
'$loadertext ...', // Use the dynamic text here
style: const TextStyle(
fontSize: 16,
decoration: TextDecoration.none,
color:
Colors.white, // Set the text color to your preference
),
),
const SizedBox(height: 16),
],
),
);
});
}
showAlertDialog(BuildContext context, bool val) {
Widget okButton = TextButton(
child: const Text("Cancel"),
......
......@@ -166,6 +166,7 @@ class _Home extends State<Home> {
),
const Padding(padding: EdgeInsets.only(left: 10, bottom: 10)),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
......@@ -236,6 +237,7 @@ class _Home extends State<Home> {
),
const Padding(padding: EdgeInsets.only(left: 10, bottom: 10)),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
......@@ -324,8 +326,7 @@ class _Home extends State<Home> {
),
padding: const EdgeInsets.all(12),
child: const Column(
mainAxisAlignment: MainAxisAlignment
.end, // Align content at the bottom
mainAxisAlignment: MainAxisAlignment.end, // Align content at the bottom
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
......@@ -869,16 +870,14 @@ class _Home extends State<Home> {
width: MediaQuery.of(context).size.width * 0.90,
child: GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) =>
// const Identifyproduct()),
// );
Navigator.push(context,
MaterialPageRoute(
builder: (context) =>
const Identifyproduct()),
);
},
child: Container(
margin: const EdgeInsets.only(
left: 20, top: 0, right: 2, bottom: 0),
margin: const EdgeInsets.only(left: 20, top: 0, right: 2, bottom: 0),
width: MediaQuery.of(context).size.width * 0.100,
height: MediaQuery.of(context).size.width * 0.22,
padding: const EdgeInsets.all(5),
......@@ -902,7 +901,7 @@ class _Home extends State<Home> {
height: 42,
), // replace with your image
const Text(
'\t\t\t\t\t\t IDENTIFY PRODUCT',
'\t\t\t\t\t\t DETECT ATTRIBUTES',
style: Constants.buttonsfontStyle,
)
],
......
......@@ -7,6 +7,7 @@ import 'package:image_picker/image_picker.dart';
import 'package:vasthram/Constants.dart';
import 'package:vasthram/CustomAlertDialog.dart';
import 'package:vasthram/RemoteData.dart';
import 'CameraScreen.dart';
class Identifyproduct extends StatefulWidget {
const Identifyproduct({super.key});
......@@ -21,24 +22,21 @@ class _Identifyproduct extends State<Identifyproduct> {
XFile? image;
bool isloading = false;
bool isVisible = true;
bool isData = false;
bool isData = false;
String? graph;
String? graph1;
Uint8List? bytes;
Uint8List? bytes1;
var bodycolor = '';
var bodydesigncolor = '';
var bordercolor = '';
var bordersize = '';
var borderworkcolor = '';
double bordersize = 0.0;
var stylecode = '';
var status = '';
int similarsale = 0;
int similarstock = 0;
late PageController _pageController;
List<Widget> pages = [];
Uint8List? imageBytes;
List<dynamic>? embedding;
String? _base64Image;
void _showPicker(BuildContext context) {
showDialog(
......@@ -58,8 +56,8 @@ class _Identifyproduct extends State<Identifyproduct> {
style: Constants.dialogbuttonstyle,
),
onTap: () {
_getImageFromCamera(0);
Navigator.of(context).pop();
_navigateToCameraScreen();
},
),
const Padding(padding: EdgeInsets.all(8.0)),
......@@ -81,17 +79,52 @@ class _Identifyproduct extends State<Identifyproduct> {
);
}
Future<void> _getImageFromCamera(int index) async {
image = await _picker.pickImage(source: ImageSource.camera);
if (image != null) {
setState(() {
imagefile = File(image!.path);
isVisible = true;
isData = false;
//getImage(imagefile);
});
Future<void> _navigateToCameraScreen() async {
if (kDebugMode) {
print('Hitting or not');
}
try {
final imageFile1 = await Navigator.push<File>(
context,
MaterialPageRoute(builder: (context) => CameraScreen()),
);
if (imageFile1 != null) {
if (kDebugMode) {
print('Camera Capture ==========> $imageFile1');
}
imagefile = imageFile1;
final bytes = await imageFile1.readAsBytes();
final base64String1 = base64Encode(bytes);
setState(() {
_base64Image = base64String1;
});
getStatus(imagefile, 'camera');
}
} catch (e) {
if (kDebugMode) {
print('Error navigating to CameraScreen: $e');
}
}
}
Future<void> getStatus(File? imagefile, String type) async {
setState(() {
isloading = true; // Set loading state to true
});
bool isInternetConnected = await Constants.checkInternetConnectivity();
if (isInternetConnected) {
Constants.Showindicator(context, 'Detecting Saree');
var upload1 = await RemoteData().uploadimage(imagefile!, '');
if (upload1 != null) {
setState(() {
isloading = false;
});
var jsonResponse = jsonDecode(upload1);
await Future.delayed(const Duration(seconds: 1));
updateUI(jsonResponse, type);
}
} else {
image = await _picker.pickImage(source: ImageSource.camera);
setDialog('Check your internet connection');
}
}
......@@ -106,6 +139,7 @@ class _Identifyproduct extends State<Identifyproduct> {
isVisible = true;
isData = false;
});
getStatus(imagefile, 'gallery');
}
}
......@@ -177,11 +211,11 @@ class _Identifyproduct extends State<Identifyproduct> {
),
),
padding: const EdgeInsets.all(12),
child: Column(
child: const Column(
children: [
Text(
similarstock.toString(),
style: const TextStyle(
'',
style: TextStyle(
fontSize: 15,
color: Color.fromARGB(255, 69, 66, 121),
),
......@@ -193,13 +227,6 @@ class _Identifyproduct extends State<Identifyproduct> {
],
),
const Padding(padding: EdgeInsets.only(left: 10, top: 10)),
Container(
color: const Color.fromRGBO(222, 221, 220, 1),
child: Image.memory(
bytes!,
fit: BoxFit.cover, // Adjust as needed
),
),
],
),
);
......@@ -258,11 +285,11 @@ class _Identifyproduct extends State<Identifyproduct> {
),
),
padding: const EdgeInsets.all(12),
child: Column(
child: const Column(
children: [
Text(
similarsale.toString(),
style: const TextStyle(
'',
style: TextStyle(
fontSize: 15,
color: Color.fromARGB(255, 69, 66, 121),
),
......@@ -290,11 +317,7 @@ class _Identifyproduct extends State<Identifyproduct> {
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
if (bodycolor.isNotEmpty ||
bodydesigncolor.isNotEmpty ||
bordercolor.isNotEmpty ||
bordersize.isNotEmpty ||
borderworkcolor.isNotEmpty)
if (bodycolor.isNotEmpty || bordercolor.isNotEmpty)
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
......@@ -383,73 +406,6 @@ class _Identifyproduct extends State<Identifyproduct> {
bottomLeft: Radius.circular(10),
),
border: Border.all(
color: Colors.white,
width: 1,
),
),
padding: const EdgeInsets.all(12),
child: const Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'\t BODY DESIGN COLOR: \t',
style: TextStyle(
fontSize: 14,
color: Colors.white,
),
textAlign: TextAlign.right,
),
],
),
),
),
Flexible(
flex: 4,
fit: FlexFit.tight,
child: Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 255, 255, 255),
borderRadius: const BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
border: Border.all(
color: Colors.white,
),
),
padding: const EdgeInsets.all(12),
child: Column(
children: [
Text(
bodydesigncolor,
style: const TextStyle(
fontSize: 15,
color: Color.fromARGB(255, 69, 66, 121),
),
),
],
),
),
),
],
),
const Padding(padding: EdgeInsets.only(left: 10, bottom: 8)),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
flex: 6,
fit: FlexFit.tight,
child: Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 69, 66, 121),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
border: Border.all(
color: Colors.white, // Set border color to white
width: 1, // Set border width
),
......@@ -509,74 +465,6 @@ class _Identifyproduct extends State<Identifyproduct> {
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
flex: 6,
fit: FlexFit.tight,
child: Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 69, 66, 121),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
border: Border.all(
color: Colors.white,
width: 1,
),
),
padding: const EdgeInsets.all(12),
child: const Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'\t BORDER WORK COLOR: \t',
style: TextStyle(
fontSize: 14,
color: Colors.white,
),
textAlign: TextAlign.right,
),
],
),
),
),
Flexible(
flex: 4,
fit: FlexFit.tight,
child: Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 255, 255, 255),
borderRadius: const BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
border: Border.all(
color: Colors.white,
width: 1,
),
),
padding: const EdgeInsets.all(12),
child: Column(
children: [
Text(
borderworkcolor,
style: const TextStyle(
fontSize: 15,
color: Color.fromARGB(255, 69, 66, 121),
),
),
],
),
),
),
],
),
const Padding(padding: EdgeInsets.only(left: 10, bottom: 8)),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
flex: 6, // 60% of the width
fit: FlexFit.tight,
child: Container(
......@@ -628,7 +516,7 @@ class _Identifyproduct extends State<Identifyproduct> {
child: Column(
children: [
Text(
bordersize,
bordersize.toString(),
style: const TextStyle(
fontSize: 15,
color: Color.fromARGB(255, 69, 66, 121),
......@@ -642,74 +530,74 @@ class _Identifyproduct extends State<Identifyproduct> {
),
//stylecode.isNotEmpty
const Padding(padding: EdgeInsets.only(left: 10, bottom: 8)),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
flex: 6, // 60% of the width
fit: FlexFit.tight,
child: Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 69, 66, 121),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
border: Border.all(
color: Colors.white, // Set border color to white
width: 1, // Set border width
),
),
padding: const EdgeInsets.all(12),
child: const Column(
mainAxisAlignment: MainAxisAlignment
.end, // Align content at the bottom
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'\t STYLE CODE: \t',
style: TextStyle(
fontSize: 14,
color: Colors.white,
),
textAlign: TextAlign.right,
),
],
),
),
),
Flexible(
flex: 4, // 40% of the width
fit: FlexFit.tight,
child: Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 255, 255, 255),
borderRadius: const BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
border: Border.all(
color: Colors.white, // Set border color to white
width: 1, // Set border width
),
),
padding: const EdgeInsets.all(12),
child: Column(
children: [
Text(
stylecode,
style: const TextStyle(
fontSize: 15,
color: Color.fromARGB(255, 69, 66, 121),
),
),
],
),
),
),
],
),
//const Padding(padding: EdgeInsets.only(left: 10, bottom: 8)),
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Flexible(
// flex: 6, // 60% of the width
// fit: FlexFit.tight,
// child: Container(
// decoration: BoxDecoration(
// color: const Color.fromARGB(255, 69, 66, 121),
// borderRadius: const BorderRadius.only(
// topLeft: Radius.circular(10),
// bottomLeft: Radius.circular(10),
// ),
// border: Border.all(
// color: Colors.white, // Set border color to white
// width: 1, // Set border width
// ),
// ),
// padding: const EdgeInsets.all(12),
// child: const Column(
// mainAxisAlignment: MainAxisAlignment
// .end, // Align content at the bottom
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Text(
// '\t STYLE CODE: \t',
// style: TextStyle(
// fontSize: 14,
// color: Colors.white,
// ),
// textAlign: TextAlign.right,
// ),
// ],
// ),
// ),
// ),
// Flexible(
// flex: 4, // 40% of the width
// fit: FlexFit.tight,
// child: Container(
// decoration: BoxDecoration(
// color: const Color.fromARGB(255, 255, 255, 255),
// borderRadius: const BorderRadius.only(
// topRight: Radius.circular(10),
// bottomRight: Radius.circular(10),
// ),
// border: Border.all(
// color: Colors.white, // Set border color to white
// width: 1, // Set border width
// ),
// ),
// padding: const EdgeInsets.all(12),
// child: Column(
// children: [
// Text(
// stylecode,
// style: const TextStyle(
// fontSize: 15,
// color: Color.fromARGB(255, 69, 66, 121),
// ),
// ),
// ],
// ),
// ),
// ),
// ],
// ),
],
)
else
......@@ -783,22 +671,19 @@ class _Identifyproduct extends State<Identifyproduct> {
_showPicker(context);
},
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.88,
width: MediaQuery.of(context).size.width * 0.90,
height: MediaQuery.of(context).size.height * 0.50,
child: imagefile != null
? Image.file(
imagefile!,
child: _base64Image != null
? Image.memory(
base64Decode(_base64Image!),
fit: BoxFit.cover,
)
: Center(
child: Image.asset(
'assets/images/camera.png',
width:
MediaQuery.of(context).size.width *
0.50, // Adjusted width
height:
MediaQuery.of(context).size.height *
0.35, // Adjusted height
width: MediaQuery.of(context).size.width * 0.50, // Adjusted width
height: MediaQuery.of(context).size.height * 0.35, // Adjusted height
fit: BoxFit.cover,
),
),
),
......@@ -814,97 +699,14 @@ class _Identifyproduct extends State<Identifyproduct> {
controller: _pageController,
children: pages = [
buildPage1('Page 1'),
buildPage2('Page 2'),
buildPage3('Page 3'),
//buildPage2('Page 2'),
//buildPage3('Page 3'),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.28,
),
Visibility(
visible: isVisible,
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.90,
child: GestureDetector(
onTap: () async {
if (imagefile == null) {
setDialog('Please Capture Image');
} else {
setState(() {
isloading = true; // Set loading state to true
});
bool isInternetConnected =
await Constants.checkInternetConnectivity();
if (isInternetConnected) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return const Center(
child: CircularProgressIndicator(
color: Color.fromARGB(255, 69, 66, 121),
),
);
});
var upload = await RemoteData()
.uploadimage(imagefile!, '');
if (upload != null) {
setState(() {
isloading = false;
});
var jsonResponse = jsonDecode(upload);
await Future.delayed(
const Duration(seconds: 1));
updateUI(jsonResponse);
}
if (Navigator.of(context).canPop()) {
if (kDebugMode) {
print('Testing =========>');
}
Navigator.of(context).pop();
}
} else {
setDialog('Check your internet connection');
}
}
},
child: Container(
margin: const EdgeInsets.only(
left: 10, top: 0, right: 2, bottom: 0),
width: MediaQuery.of(context).size.width * 0.100,
height: MediaQuery.of(context).size.width * 0.13,
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.bottomRight,
colors: [
Color.fromARGB(255, 227, 144, 214),
//Color(0xFFC2185B),
Color.fromARGB(255, 125, 174, 251),
],
),
borderRadius: BorderRadius.circular(50),
),
child: const Row(
children: [
Text('\t\t'),
Expanded(
child: Center(
child: Text(
'IDENTIFY PRODUCT',
style: Constants.buttonsfontStyle,
textAlign: TextAlign.center,
),
),
),
],
),
),
),
),
),
const Text('\n\n')
],
),
......@@ -915,35 +717,89 @@ class _Identifyproduct extends State<Identifyproduct> {
);
}
void updateUI(Map<String, dynamic> jsonResponse) {
Future<void> updateUI(Map<String, dynamic> jsonResponse1, String type) async {
Navigator.of(context).pop();
print('Response Data : $jsonResponse1');
var saree = jsonResponse1['saree_detected'];
if (kDebugMode) {
print(saree);
}
if (saree == 'Yes') {
var bodyimage = jsonResponse1['body_metrics'][3];
var annotated_image = jsonResponse1['annotated_image'];
setState(() {
_base64Image = annotated_image;
});
print(bodyimage);
try {
Constants.Showindicator(context, 'Identify Product');
var upload = await RemoteData().detectAttributes(imagefile!, bodyimage);
var json = jsonDecode(upload!);
await Future.delayed(const Duration(seconds: 1));
getupdate(json);
} catch (e) {
print('verified$e');
return;
}
return;
} else {
if (type == 'camera') {
showDialog(
context: context,
builder: (BuildContext context) {
return CustomAlertDialog(
titleText: 'WARNING ! \t',
contentText: 'Saree Not Detected',
buttonText: 'No',
onButtonPressed: () {
Navigator.of(context).pop();
},
secondButtonText: 'Yes',
onSecondButtonPressed: () {
Navigator.of(context).pop();
Future.delayed(const Duration(milliseconds: 200), () {
_navigateToCameraScreen();
});
},
icon: const Icon(Icons.info),
);
},
);
} else {
_getImageFromGallery(context);
}
}
}
void getupdate(Map<String, dynamic> jsonResponse) {
print('Hitting ot npt $jsonResponse');
Navigator.of(context).pop();
setState(() {
isloading = false;
});
isData = true;
//isVisible = false;
setState(() {
isData = true;
isVisible = false;
status = jsonResponse['status'];
status = jsonResponse['status']!;
print(status);
if (status == 'Success') {
bodycolor = jsonResponse['body_color'];
bodydesigncolor = jsonResponse['body_design_color'];
bordercolor = jsonResponse['border_color'];
bodycolor = jsonResponse['body_color']!;
bordercolor = jsonResponse['border_color']!;
bordersize = jsonResponse['border_size'];
borderworkcolor = jsonResponse['border_design_color'];
stylecode = jsonResponse['stylecode'];
similarsale = jsonResponse['similarsale'];
similarstock = jsonResponse['similarstock'];
bytes = base64.decode(jsonResponse['similarstockgraph']);
bytes1 = base64.decode(jsonResponse['similarsalegraph']);
_base64Image = jsonResponse['image'];
//stylecode = jsonResponse['stylecode']!;
} else {
setDialog('Could not found image');
setDialog('Could not found IdentifyProduct');
bodycolor = '';
bodydesigncolor = '';
bordercolor = '';
bordersize = '';
borderworkcolor = '';
bordersize = 0.0;
stylecode = '';
bytes!.clear();
bytes1!.clear();
embedding!.clear();
}
});
print('Hitting ot npt $jsonResponse');
}
void setDialog(String text) {
......
......@@ -5,7 +5,6 @@ import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:tflite_flutter/tflite_flutter.dart';
import 'package:vasthram/CameraScreen.dart';
import 'package:vasthram/Constants.dart';
import 'package:vasthram/RemoteData.dart';
......@@ -42,13 +41,9 @@ class _Identifystylecode extends State<Identifystylecode> {
List<Widget> pages = [];
Uint8List? imageBytes;
List<dynamic>? embedding;
late Interpreter _interpreter;
bool _isCameraInitialized = false;
bool _isPictureTaken = false;
List<Stylecode>? closestStylecodes;
File? imagefile0;
CameraController? controller;
late Future<void> _initializeControllerFuture;
String? _base64Image;
// void getImage(File? imagefile) {
......@@ -87,8 +82,7 @@ class _Identifystylecode extends State<Identifystylecode> {
Future<void> initializeCamera() async {
final cameras = await availableCameras();
final frontCamera = cameras.firstWhere(
(camera) => camera.lensDirection == CameraLensDirection.back);
final frontCamera = cameras.firstWhere((camera) => camera.lensDirection == CameraLensDirection.back);
if (frontCamera == null) {
if (kDebugMode) {
print('No front camera found');
......@@ -99,36 +93,12 @@ class _Identifystylecode extends State<Identifystylecode> {
await controller!.initialize();
}
Future<void> takePicture() async {
if (controller == null || !controller!.value.isInitialized) {
await initializeCamera();
}
// Take a picture
final XFile? picture = await controller!.takePicture();
if (picture != null) {
setState(() {
imagefile = File(picture.path);
_isPictureTaken = true;
});
}
print('Picture taken at: ${picture!.path}');
}
Future<void> _navigateToCameraScreen() async {
if (kDebugMode) {
print('Hitting or not');
}
try {
final imageFile1 = await Navigator.push<File>(
context,
MaterialPageRoute(builder: (context) => CameraScreen()),
);
final imageFile1 = await Navigator.push<File>(context, MaterialPageRoute(builder: (context) => CameraScreen()));
if (imageFile1 != null) {
if (kDebugMode) {
print('Camera Capture ==========> $imageFile1');
}
imagefile = imageFile1;
final bytes = await imageFile1.readAsBytes();
imagefile = imageFile1;
final bytes = await imageFile1.readAsBytes();
final base64String1 = base64Encode(bytes);
setState(() {
_base64Image = base64String1;
......@@ -184,23 +154,23 @@ class _Identifystylecode extends State<Identifystylecode> {
);
}
Future<void> _getImageFromCamera() async {
try {
final pickedFile = await _picker.pickImage(source: ImageSource.camera);
//Navigator.of(context).pop();
if (pickedFile != null) {
setState(() {
imagefile = File(pickedFile.path);
isVisible = true;
isData = false;
});
} else {
print("No image picked");
}
} catch (e) {
print("Error while picking image from camera: $e");
}
}
// Future<void> _getImageFromCamera() async {
// try {
// final pickedFile = await _picker.pickImage(source: ImageSource.camera);
// //Navigator.of(context).pop();
// if (pickedFile != null) {
// setState(() {
// imagefile = File(pickedFile.path);
// isVisible = true;
// isData = false;
// });
// } else {
// print("No image picked");
// }
// } catch (e) {
// print("Error while picking image from camera: $e");
// }
// }
Future<void> _getImageFromGallery(BuildContext context) async {
image = await _picker.pickImage(source: ImageSource.gallery);
......@@ -224,24 +194,22 @@ class _Identifystylecode extends State<Identifystylecode> {
//loadModel();
}
Future<void> loadModel() async {
String? modelPath = 'assets/images/model.tflite';
if (kDebugMode) {
print('Loading interpreter options...');
}
final interpreterOptions = InterpreterOptions();
if (Platform.isAndroid) {
interpreterOptions.addDelegate(XNNPackDelegate());
}
if (Platform.isIOS) {
interpreterOptions.addDelegate(GpuDelegate());
}
if (kDebugMode) {
print('Loading interpreter...');
}
_interpreter =
await Interpreter.fromAsset(modelPath, options: interpreterOptions);
}
// Future<void> loadModel() async {
// String? modelPath = 'assets/images/model.tflite';
// if (kDebugMode) {
// print('Loading interpreter options...');
// }
// final interpreterOptions = InterpreterOptions();
// if (Platform.isAndroid) {
// interpreterOptions.addDelegate(XNNPackDelegate());
// }
// if (Platform.isIOS) {
// interpreterOptions.addDelegate(GpuDelegate());
// }
// if (kDebugMode) {
// print('Loading interpreter...');
// }
// }
@override
void dispose() {
......@@ -323,7 +291,7 @@ class _Identifystylecode extends State<Identifystylecode> {
color: const Color.fromRGBO(222, 221, 220, 1),
child: Image.memory(
bytes!,
fit: BoxFit.cover, // Adjust as needed
fit: BoxFit.contain, // Adjust as needed
),
),
],
......@@ -418,71 +386,117 @@ class _Identifystylecode extends State<Identifystylecode> {
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
if (closestStylecodes!.isNotEmpty)
ListView.builder(
shrinkWrap: true,
itemCount: closestStylecodes!.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(
'Style Code \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: ${closestStylecodes![index].styleCode}',
style: Constants.headerfontStyle,
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
Expanded(
// Use Expanded to ensure ListView gets the remaining space
child: ListView.builder(
itemCount: closestStylecodes!.length,
itemBuilder: (context, index) {
return Card(
child: Column(
children: [
Text(
'Similarity Percentage : ${closestStylecodes![index].SimilarityPercentage ?? 'None'}${closestStylecodes![index].SimilarityPercentage != 'None' ? '%' : ''}',
style: Constants.headerfontStyle,
ListTile(
title: Text(
'Style Code \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: ${closestStylecodes![index].styleCode!.toUpperCase()}',
style: Constants.headerfontStyle,
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 8,
),
Text(
'Similarity Percentage\t: ${closestStylecodes![index].SimilarityPercentage ?? 'None'}${closestStylecodes![index].SimilarityPercentage != 'None' ? '%' : ''}',
style: Constants.headerfontStyle,
),
],
),
onTap: () {},
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Constants.Showindicator(context, 'Loading Data ...');
getStock(closestStylecodes![index].styleCode);
},
style: ElevatedButton.styleFrom(backgroundColor: const Color.fromARGB(255, 69, 66, 121),),
child: const Text(
'Stock',
style: TextStyle(color: Colors.white),
),
),
const SizedBox(width: 16),
ElevatedButton(
onPressed: () {
Constants.Showindicator(context, 'Loading Data ...');
getSale(closestStylecodes![index].styleCode);
},
style: ElevatedButton.styleFrom(backgroundColor:const Color.fromARGB(255, 69, 66, 121)),
child: const Text('\tSale\t',style: TextStyle(color: Colors.white)),
),
const SizedBox(width: 16),
ElevatedButton(
onPressed: () {
if (closestStylecodes![index].similarImagePath !=
'No Saree') {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Style Code Details'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'Style Code: ${closestStylecodes![index].styleCode}',
style: Constants.headerfontStyle,
),
Text(
'Similarity Percentage: ${closestStylecodes![index].SimilarityPercentage ?? 'None'}${closestStylecodes![index].SimilarityPercentage != 'None' ? '%' : ''}',
style: Constants.headerfontStyle,
),
Image.network(
closestStylecodes![index]
.similarImagePath!,
width: 200,
height: 200,
),
],
),
actions: [
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color.fromARGB(
255, 69, 66, 121), // Background color
),
child: const Text(
'\tView\t',
style: TextStyle(color: Colors.white),
),
),
],
),
const SizedBox(height: 5),
],
),
onTap: () {
if (closestStylecodes![index].similarImagePath ==
'None') {
} else if (closestStylecodes![index].similarImagePath ==
'None') {
} else {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Style Code Details'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Style Code: ${closestStylecodes![index].styleCode}',
style: Constants.headerfontStyle,
),
Text(
'Similarity Percentage\t\t\t\t: ${closestStylecodes![index].SimilarityPercentage ?? 'None'}${closestStylecodes![index].SimilarityPercentage != 'None' ? '%' : ''}',
style: Constants.headerfontStyle,
),
Image.network(
closestStylecodes![index].similarImagePath!,
width: 200,
height: 200,
),
],
),
actions: [
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
},
),
);
},
);
},
),
)
else
const SizedBox(
......@@ -505,6 +519,70 @@ class _Identifystylecode extends State<Identifystylecode> {
);
}
getStock(String? text) {
var response = RemoteData().stockData(text!);
response.then((value) {
Navigator.of(context).pop();
final Map<String, dynamic> data = jsonDecode(value);
_showListDialog(context, data, 'Stock Data');
});
}
getSale(String? text) {
var response = RemoteData().saleData(text!);
response.then((value) {
Navigator.of(context).pop();
final Map<String, dynamic> data = jsonDecode(value);
_showListDialog(context, data, 'Sale Data');
});
}
void _showListDialog(
BuildContext context, Map<String, dynamic> data, String header) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(header),
content: SizedBox(
// Set the height and width of the container
width: double.maxFinite,
child: ListView.builder(
shrinkWrap: true,
itemCount: data.keys.length,
itemBuilder: (BuildContext context, int index) {
String key = data.keys.elementAt(index);
String value = data[key].toString();
if (key == 'Average GST Margin 90 days') {
value = '₹ $value';
}
if (key == 'STORES') {
value = value.substring(1, value.length - 1);
}
return ListTile(
title: Text(key),
subtitle: Text(
value,
style: const TextStyle(
color: Color.fromARGB(255, 69, 66, 121)),
),
);
},
),
),
actions: [
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
......@@ -616,85 +694,6 @@ class _Identifystylecode extends State<Identifystylecode> {
SizedBox(
height: MediaQuery.of(context).size.height * 0.28,
),
// Visibility(
// visible: isVisible,
// child: SizedBox(
// width: MediaQuery.of(context).size.width * 0.90,
// child: GestureDetector(
// onTap: () async {
// if (imagefile == null) {
// setDialog('Please Capture Image');
// } else {
// setState(() {
// isloading = true; // Set loading state to true
// });
// bool isInternetConnected =
// await Constants.checkInternetConnectivity();
// if (isInternetConnected) {
// showDialog(
// context: context,
// barrierDismissible: false,
// builder: (context) {
// return const Center(
// child: CircularProgressIndicator(
// color: Color.fromARGB(255, 69, 66, 121),
// ),
// );
// });
// var upload1 = await RemoteData()
// .uploadimage(imagefile!, '');
// if (upload1 != null) {
// setState(() {
// isloading = false;
// });
// var jsonResponse = jsonDecode(upload1);
// await Future.delayed(
// const Duration(seconds: 1));
// updateUI(jsonResponse);
// }
// if (Navigator.of(context).canPop()) {
// //Navigator.of(context).pop();
// }
// } else {
// setDialog('Check your internet connection');
// }
// }
// },
// child: Container(
// margin: const EdgeInsets.only(
// left: 10, top: 0, right: 2, bottom: 0),
// width: MediaQuery.of(context).size.width * 0.100,
// height: MediaQuery.of(context).size.width * 0.13,
// padding: const EdgeInsets.all(5),
// decoration: BoxDecoration(
// gradient: const LinearGradient(
// begin: Alignment.bottomLeft,
// end: Alignment.bottomRight,
// colors: [
// Color.fromARGB(255, 227, 144, 214),
// Color.fromARGB(255, 125, 174, 251),
// ],
// ),
// borderRadius: BorderRadius.circular(50),
// ),
// child: const Row(
// children: [
// Text('\t\t'),
// Expanded(
// child: Center(
// child: Text(
// 'IDENTIFY STYLE CODE',
// style: Constants.buttonsfontStyle,
// textAlign: TextAlign.center,
// ),
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// ),
const Text('\n\n')
],
),
......@@ -728,26 +727,27 @@ class _Identifystylecode extends State<Identifystylecode> {
Future<void> updateUI(Map<String, dynamic> jsonResponse1, String type) async {
Navigator.of(context).pop();
print('Response Data : $jsonResponse1');
//print('Response Data : $jsonResponse1');
var saree = jsonResponse1['saree_detected'];
if (kDebugMode) {
print(saree);
}
if (saree == 'Yes') {
var bodyimage = jsonResponse1['body_metrics'][0];
var annotated_image = jsonResponse1['annotated_image'];
var bodyimage = jsonResponse1['body_metrics'][3];
var annotatedimage = jsonResponse1['annotated_image'];
setState(() {
_base64Image = annotated_image;
_base64Image = annotatedimage;
});
print(bodyimage);
//print(bodyimage);
try {
Constants.Showindicator(context, 'Identify stylecode');
var upload =
await RemoteData().IdentifyStyleCode(imagefile!, bodyimage);
//var json = jsonDecode(upload!);
await Future.delayed(const Duration(seconds: 1));
getupdate(upload!);
} catch (e) {
print(e);
//print(e);
return;
}
return;
......@@ -782,11 +782,10 @@ class _Identifystylecode extends State<Identifystylecode> {
void getupdate(var jsonResponse) {
print('Hitting ot npt $jsonResponse');
//Navigator.of(context).pop();
var json =
'[{"Similarity Percentage":"12","Stylecode":"Black","imageURL":"http://google.com"}]';
//List<dynamic> closestStylecodesList = jsonDecode(jsonResponse);
//jsonResponse['Closest Stylecodes'];
Navigator.of(context).pop();
setState(() {
isloading = false;
});
isData = true;
//isVisible = false;
setState(() {
......@@ -807,16 +806,7 @@ class _Identifystylecode extends State<Identifystylecode> {
});
bool isInternetConnected = await Constants.checkInternetConnectivity();
if (isInternetConnected) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return const Center(
child: CircularProgressIndicator(
color: Color.fromARGB(255, 69, 66, 121),
),
);
});
Constants.Showindicator(context, 'Detecting Saree');
var upload1 = await RemoteData().uploadimage(imagefile!, '');
if (upload1 != null) {
setState(() {
......@@ -833,7 +823,7 @@ class _Identifystylecode extends State<Identifystylecode> {
}
class Stylecode {
final String? SimilarityPercentage;
final int? SimilarityPercentage;
final String? similarImagePath;
final String? styleCode;
......
......@@ -6,13 +6,17 @@ import 'package:http/http.dart' as http;
class RemoteData {
final String loginUrl = 'http://vaman.plutokm.com/login';
final String Uploadimage = 'http://vaman.plutokm.com/vasthram_mobile';
final String Identifystylecode = 'https://vaman.plutokm.com/get_vasthram_style_code';
final String imageupload = 'http://vaman.plutokm.com/vasthram_mobile';
final String identifystylecode = 'https://vaman.plutokm.com/get_vasthram_style_code';
final String registerstylecode = 'https://vaman.plutokm.com/register_style_code';
final String detectattributes = 'https://vaman.plutokm.com/detect_attributes';
final String sale = 'https://vaman.plutokm.com/stylecode_sales_data';
final String stock = 'https://vaman.plutokm.com/stylecode_stock_data';
final String type = 'Content-Type';
final String appjson = 'application/json';
Future<String> getLoginRequest (String loginid, String pass, String token) async {
Future<String> getLoginRequest(
String loginid, String pass, String token) async {
Map<String, dynamic> body = {
'login_id': loginid,
'password': pass,
......@@ -36,16 +40,19 @@ class RemoteData {
}
}
Future<String?> uploadimage(File imagepath, String embedding) async {
Future<String> stockData(String stylecode) async {
print(stylecode);
try {
final request = http.MultipartRequest('POST', Uri.parse('http://vaman.plutokm.com/detect_saree'));
request.files.add(await http.MultipartFile.fromPath('image', imagepath.path));
final request = http.MultipartRequest('POST', Uri.parse(stock));
request.files.add(http.MultipartFile.fromString('stylecode', stylecode));
//request.files.add(await http.MultipartFile.fromPath('embedding', embedding));
var response = await request.send();
var response = await request.send();
var responseString = await response.stream.bytesToString();
if (kDebugMode) {
print('Response :$responseString');
}
print(response.statusCode);
if (response.statusCode == 200) {
return responseString;
} else {
......@@ -59,18 +66,18 @@ class RemoteData {
return '';
}
Future<String?> IdentifyStyleCode(File imagepath, String bodyimagepath) async {
print('Identify Stylecode $bodyimagepath');
Future<String> saleData(String stylecode) async {
print(stylecode);
try {
final request = http.MultipartRequest('POST', Uri.parse(Identifystylecode));
request.files.add(await http.MultipartFile.fromPath('image', imagepath.path));
request.files.add(await http.MultipartFile.fromString('body_image_path', bodyimagepath));
final request = http.MultipartRequest('POST', Uri.parse(sale));
request.files.add(http.MultipartFile.fromString('stylecode', stylecode));
//request.files.add(await http.MultipartFile.fromPath('embedding', embedding));
var response = await request.send();
var response = await request.send();
var responseString = await response.stream.bytesToString();
if (kDebugMode) {
print('Response :$responseString');
}
print(response.statusCode);
if (response.statusCode == 200) {
return responseString;
} else {
......@@ -84,16 +91,102 @@ class RemoteData {
return '';
}
Future<String?> registerStyleCode(File imagepath, var embedding, String stylecode) async {
print('Register Style Code : $stylecode');
Future<String?> uploadimage(File imagepath, String embedding) async {
try {
final request = http.MultipartRequest('POST', Uri.parse(registerstylecode));
request.files.add(await http.MultipartFile.fromPath('image', imagepath.path));
request.files.add(http.MultipartFile.fromString('body_image_path', embedding));
//request.fields('style_code', stylecode);
request.fields['style_code'] = stylecode;
final request = http.MultipartRequest(
'POST', Uri.parse('http://vaman.plutokm.com/detect_saree'));
request.files
.add(await http.MultipartFile.fromPath('image', imagepath.path));
var response = await request.send();
var responseString = await response.stream.bytesToString();
if (kDebugMode) {
print('Response :$responseString');
}
if (response.statusCode == 200) {
return responseString;
} else {
return responseString;
}
} catch (e) {
if (kDebugMode) {
print(e);
}
}
return '';
}
Future<String?> IdentifyStyleCode(
File imagepath, String bodyimagepath) async {
if (kDebugMode) {
print('Identify Stylecode $bodyimagepath');
}
try {
final request =
http.MultipartRequest('POST', Uri.parse(identifystylecode));
request.files
.add(await http.MultipartFile.fromPath('image', imagepath.path));
request.files
.add(http.MultipartFile.fromString('body_image_path', bodyimagepath));
//request.files.add(await http.MultipartFile.fromPath('embedding', embedding));
var response = await request.send();
var response = await request.send();
var responseString = await response.stream.bytesToString();
if (kDebugMode) {
print('Response :$responseString');
}
if (response.statusCode == 200) {
return responseString;
} else {
return responseString;
}
} catch (e) {
if (kDebugMode) {
print(e);
}
}
return '';
}
Future<String?> detectAttributes(File imagepath, String image) async {
try {
final request =
http.MultipartRequest('POST', Uri.parse(detectattributes));
request.files
.add(await http.MultipartFile.fromPath('image', imagepath.path));
request.files
.add(http.MultipartFile.fromString('body_image_path', image));
//request.fields['style_code'] = stylecode;
var response = await request.send();
var responseString = await response.stream.bytesToString();
if (kDebugMode) {
print('Response :$responseString');
}
if (response.statusCode == 200) {
return responseString;
} else {
return responseString;
}
} catch (e) {
if (kDebugMode) {
print(e);
}
}
return '';
}
Future<String?> registerStyleCode(
File imagepath, var embedding, String stylecode) async {
if (kDebugMode) {
print('Register Style Code : $stylecode');
}
try {
final request =
http.MultipartRequest('POST', Uri.parse(registerstylecode));
request.files
.add(await http.MultipartFile.fromPath('image', imagepath.path));
request.files
.add(http.MultipartFile.fromString('body_image_path', embedding));
request.fields['style_code'] = stylecode;
var response = await request.send();
var responseString = await response.stream.bytesToString();
if (kDebugMode) {
print('Response :$responseString');
......@@ -113,7 +206,8 @@ class RemoteData {
Future<String?> searchbybarcode(String barcode) async {
var client = http.Client();
var res = await client.get(Uri.parse('https://vaman.plutokm.com/get_vas_barcode_image/$barcode'));
var res = await client.get(
Uri.parse('https://vaman.plutokm.com/get_vas_barcode_image/$barcode'));
if (kDebugMode) {
print(res.body);
}
......
......@@ -108,18 +108,9 @@ class _Searchbybarcode extends State<Searchbybarcode> {
bool isInternetConnected =
await Constants.checkInternetConnectivity();
if (isInternetConnected) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return const Center(
child: CircularProgressIndicator(
color: Color.fromARGB(255, 69, 66, 121),
),
);
}
);
var upload = await RemoteData().searchbybarcode(_barcode.text.trim().toUpperCase());
Constants.Showindicator(context, 'Search Barcode');
var upload = await RemoteData().searchbybarcode(
_barcode.text.trim().toUpperCase());
if (upload != null) {
var jsonResponse = jsonDecode(upload);
await Future.delayed(const Duration(seconds: 1));
......@@ -129,7 +120,7 @@ class _Searchbybarcode extends State<Searchbybarcode> {
if (kDebugMode) {
print('Testing =========>');
}
Navigator.of(context).pop();
// Navigator.of(context).pop();
}
} else {
setDialog('Check your internet connection');
......@@ -148,7 +139,6 @@ class _Searchbybarcode extends State<Searchbybarcode> {
end: Alignment.bottomRight,
colors: [
Color.fromARGB(255, 227, 144, 214),
//Color(0xFFC2185B),
Color.fromARGB(255, 125, 174, 251),
],
),
......@@ -157,7 +147,6 @@ class _Searchbybarcode extends State<Searchbybarcode> {
child: const Row(
children: [
Text('\t\t'),
// replace with your image
Expanded(
child: Center(
child: Text(
......@@ -211,15 +200,19 @@ class _Searchbybarcode extends State<Searchbybarcode> {
}
void updateUI(Map<String, dynamic> jsonResponse) {
setState(() {
var newImageUrl = jsonResponse['image_url'];
Navigator.of(context).pop();
var newImageUrl = jsonResponse['image_url'];
var status = jsonResponse['status'];
if (status == 'NotFound') {
setDialog(jsonResponse['status']);
} else {
setState(() {
imageUrl = newImageUrl;
var str = _barcode.text;
value = 'BARCODE : $str';
_barcode.clear();
});
});
}
}
void setDialog(String text) {
......
......@@ -8,6 +8,7 @@ import 'package:vasthram/SignUp.dart';
class UserPreferences {
static const String isLoggedInKey = 'isLoggedIn';
static Future<SharedPreferences> getSharedPreferences() async {
return await SharedPreferences.getInstance();
}
......@@ -27,6 +28,7 @@ class SplashScreen extends StatefulWidget {
class SplashScreenState extends State<SplashScreen> {
bool? isLoggedIn = false;
void timeToShowSplashScreenOnScreen() async {
Timer(const Duration(seconds: 5), () async {
if (!mounted) return;
......@@ -39,7 +41,8 @@ class SplashScreenState extends State<SplashScreen> {
if (kDebugMode) {
print('if condition :$isLoggedIn');
}
Navigator.push(context, MaterialPageRoute(builder: (context) => const Home()));
Navigator.push(
context, MaterialPageRoute(builder: (context) => const Home()));
} else {
Navigator.pushAndRemoveUntil(
context,
......@@ -67,19 +70,6 @@ class SplashScreenState extends State<SplashScreen> {
width: MediaQuery.of(context).size.width,
frameRate: 30, //default is 15 FPS
),
// decoration: const BoxDecoration(
// //loadingText: Text("Loading"),
// GifView.asset(
// 'assets/images/login.gif',
// height: 350,
// width: 350,
// frameRate: 30, //default is 15 FPS
// ),
// image: DecorationImage(
// image: AssetImage("assets/images/splash.gif"),
// fit: BoxFit.cover,
// ),
// ),
),
);
}
......
......@@ -117,16 +117,7 @@ class _Uploadstylecode extends State<Uploadstylecode> {
});
bool isInternetConnected = await Constants.checkInternetConnectivity();
if (isInternetConnected) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return const Center(
child: CircularProgressIndicator(
color: Color.fromARGB(255, 69, 66, 121),
),
);
});
Constants.Showindicator(context, 'Detecting Saree');
var upload = await RemoteData().uploadimage(imagefile!, '');
print(_stylecode.text);
if (upload != null) {
......@@ -686,12 +677,16 @@ class _Uploadstylecode extends State<Uploadstylecode> {
setState(() {
_base64Image = annotated_image;
});
Constants.Showindicator(context, 'Register Stylecode');
var upload = await RemoteData()
.registerStyleCode(imagefile!, bodyimage, _stylecode.text);
var json = jsonDecode(upload!);
await Future.delayed(const Duration(seconds: 1));
getupdate(json);
print(upload);
if (upload != null) {
var json = jsonDecode(upload);
await Future.delayed(const Duration(seconds: 1));
getupdate(json);
print(upload);
}
return;
} else {
showDialog(
......@@ -721,6 +716,10 @@ class _Uploadstylecode extends State<Uploadstylecode> {
void getupdate(Map<String, dynamic> jsonResponse) {
setState(() {
Navigator.of(context).pop();
setState(() {
isloading = false;
});
isVisible = false;
//{"error_message":"","reg_status":"Success"}
status = jsonResponse['reg_status'];
......@@ -736,10 +735,10 @@ class _Uploadstylecode extends State<Uploadstylecode> {
} else {
print('Else Printing ===============>');
setDialog(jsonResponse['error_message']);
setDialog(jsonResponse['reg_status']);
//bytes!.clear();
//bytes1!.clear();
embedding!.clear();
//embedding!.clear();
//Navigator.of(context).pop();
}
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment