From ca8af59f08adc2956892a6d1433d37d501dc6228 Mon Sep 17 00:00:00 2001 From: BojanDolic Date: Tue, 1 Mar 2022 13:06:26 +0100 Subject: [PATCH 1/2] Initial commit --- assets/lc_circuit.png | Bin 0 -> 15760 bytes lib/main.dart | 3 +++ .../calculators/resonant_freq_screen.dart | 22 ++++++++++++++++++ lib/screens/calculators_screen.dart | 5 ++-- 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 assets/lc_circuit.png create mode 100644 lib/screens/calculators/resonant_freq_screen.dart diff --git a/assets/lc_circuit.png b/assets/lc_circuit.png new file mode 100644 index 0000000000000000000000000000000000000000..af326f8c72efa6e8ad5466f1da2705ae51acf658 GIT binary patch literal 15760 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 const MainScreen(), CalculatorsScreen.id: (context) => const CalculatorsScreen(), CapacitorScreen.id: (context) => const CapacitorScreen(), + ResonantFrequencyScreen.id: (context) => + const ResonantFrequencyScreen(), InformationScreen.id: (context) => const InformationScreen(), }, initialRoute: MainScreen.id, diff --git a/lib/screens/calculators/resonant_freq_screen.dart b/lib/screens/calculators/resonant_freq_screen.dart new file mode 100644 index 0000000..905abfc --- /dev/null +++ b/lib/screens/calculators/resonant_freq_screen.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +class ResonantFrequencyScreen extends StatefulWidget { + const ResonantFrequencyScreen({Key? key}) : super(key: key); + + static String id = "/calculators/resfreq"; + + @override + _ResonantFrequencyScreenState createState() => + _ResonantFrequencyScreenState(); +} + +class _ResonantFrequencyScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Column( + children: [], + ), + ); + } +} diff --git a/lib/screens/calculators_screen.dart b/lib/screens/calculators_screen.dart index d133a6c..5f466e5 100644 --- a/lib/screens/calculators_screen.dart +++ b/lib/screens/calculators_screen.dart @@ -1,4 +1,5 @@ import 'package:coiler_app/screens/calculators/capacitor_screen.dart'; +import 'package:coiler_app/screens/calculators/resonant_freq_screen.dart'; import 'package:coiler_app/util/constants.dart'; import 'package:flutter/material.dart'; @@ -13,7 +14,7 @@ class CalculatorsScreen extends StatelessWidget { body: SafeArea( child: Column( children: [ - Center( + const Center( child: Padding( padding: const EdgeInsets.all(8.0), child: Text( @@ -48,7 +49,7 @@ class CalculatorsScreen extends StatelessWidget { height: 26, ), onTap: () { - //TODO Navigate + Navigator.pushNamed(context, ResonantFrequencyScreen.id); }, ), CalculatorItem( From bdfbadb9c9a9b478e5c292a2acdcd217950c0072 Mon Sep 17 00:00:00 2001 From: BojanDolic Date: Tue, 1 Mar 2022 17:08:45 +0100 Subject: [PATCH 2/2] COILER_01032022_RESFREQ Implemented resonant frequency calculator. Changes to calculator.dart and conversion.dart. --- lib/calculator/calculator.dart | 31 +++ .../calculators/resonant_freq_screen.dart | 173 ++++++++++++- lib/util/constants.dart | 18 ++ lib/util/conversion.dart | 41 ++++ lib/util/list_constants.dart | 59 +++++ lib/widgets/border_container.dart | 44 ++++ lib/widgets/input_field.dart | 81 ++++++ lib/widgets/input_field_dropdown.dart | 74 ++++++ pubspec.lock | 231 ++++++++++++++++++ pubspec.yaml | 1 + 10 files changed, 751 insertions(+), 2 deletions(-) create mode 100644 lib/calculator/calculator.dart create mode 100644 lib/util/conversion.dart create mode 100644 lib/util/list_constants.dart create mode 100644 lib/widgets/border_container.dart create mode 100644 lib/widgets/input_field.dart create mode 100644 lib/widgets/input_field_dropdown.dart diff --git a/lib/calculator/calculator.dart b/lib/calculator/calculator.dart new file mode 100644 index 0000000..4e1c5de --- /dev/null +++ b/lib/calculator/calculator.dart @@ -0,0 +1,31 @@ +import 'dart:math' as math; + +class Calculator { + double calculateMMC(double capacitance, int seriesCap, int parallelCap) { + double? _capacitance = 0.0; + + try { + var _cap = (capacitance * parallelCap) / seriesCap; + _capacitance = double.parse(_cap.toStringAsFixed(7)); + } catch (e) { + _capacitance = 0.0; + } + return _capacitance; + } + + double calculateResFrequency(double inductance, double capacitance) { + double resFreqResult = 0.0; + + var sqrtCap = math.sqrt(capacitance); + var sqrtInd = math.sqrt(inductance); + + var frequency = 1 / (2 * math.pi * sqrtInd * sqrtCap); + + /*try { + resFreqResult = double.parse(frequency.toStringAsFixed(2)); + } catch (e) { + resFreqResult = 0.0; + }*/ + return frequency; + } +} diff --git a/lib/screens/calculators/resonant_freq_screen.dart b/lib/screens/calculators/resonant_freq_screen.dart index 905abfc..e062c7c 100644 --- a/lib/screens/calculators/resonant_freq_screen.dart +++ b/lib/screens/calculators/resonant_freq_screen.dart @@ -1,3 +1,10 @@ +import 'package:coiler_app/calculator/calculator.dart'; +import 'package:coiler_app/util/constants.dart'; +import 'package:coiler_app/util/conversion.dart'; +import 'package:coiler_app/util/list_constants.dart'; +import 'package:coiler_app/widgets/border_container.dart'; +import 'package:coiler_app/widgets/input_field_dropdown.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class ResonantFrequencyScreen extends StatefulWidget { @@ -11,11 +18,173 @@ class ResonantFrequencyScreen extends StatefulWidget { } class _ResonantFrequencyScreenState extends State { + final _formKey = GlobalKey(); + + String inductance = ""; + String capacitance = ""; + String frequency = ""; + + Units inductanceUnit = Units.MICRO; + Units capacitanceUnit = Units.MICRO; + Units frequencyUnit = Units.KILO; + + TextEditingController inductanceController = TextEditingController(); + TextEditingController capacitanceController = TextEditingController(); + + void calculateFrequency() { + if (!_formKey.currentState!.validate()) { + return; + } + var inductanceTemp = double.tryParse(inductance); + var capacitanceTemp = double.tryParse(capacitance); + + if (inductanceTemp != 0 && capacitanceTemp != 0) { + var inductance = Converter() + .convertUnits(inductanceTemp, inductanceUnit, Units.DEFAULT); + var capacitance = Converter() + .convertUnits(capacitanceTemp, capacitanceUnit, Units.DEFAULT); + + var frequencyTemp = + Calculator().calculateResFrequency(inductance, capacitance); + var frequency = + Converter().convertUnits(frequencyTemp, Units.DEFAULT, frequencyUnit); + + setState(() { + this.frequency = frequency.toStringAsFixed(4); + }); + } + } + @override Widget build(BuildContext context) { return Scaffold( - body: Column( - children: [], + backgroundColor: Colors.white, + body: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 8, + ), + child: SingleChildScrollView( + child: Form( + autovalidateMode: AutovalidateMode.always, + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Align( + alignment: Alignment.center, + child: BorderContainer( + elevated: true, + child: Column( + children: [ + Image.asset( + "assets/lc_circuit.png", + height: 200, + ), + Text( + "Calculate resonant frequency of your LC circuit by entering values below.", + style: normalTextStyleOpenSans14, + textAlign: TextAlign.center, + ) + ], + ), + ), + ), + SizedBox( + height: 10, + ), + BorderContainer( + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("Frequency: $frequency"), + Container( + padding: EdgeInsets.symmetric( + horizontal: 9, + ), + decoration: BoxDecoration( + color: lightBlueColor, + borderRadius: BorderRadius.circular(9), + ), + child: DropdownButton( + value: frequencyUnit, + items: frequencyDropDownList, + borderRadius: BorderRadius.circular(9), + underline: Container(), + onChanged: (value) { + setState(() { + frequencyUnit = value!; + calculateFrequency(); + }); + }), + ), + ], + ), + ), + SizedBox( + height: 20, + ), + Padding( + padding: const EdgeInsets.symmetric( + vertical: 9, + ), + child: InputFieldDropDown( + hintText: "Enter inductance", + labelText: "Inductance", + controller: inductanceController, + onTextChanged: (text) { + setState(() { + inductance = text; + calculateFrequency(); + }); + }, + validator: (text) { + if (text == null || text.isEmpty) { + return "Input invalid"; + } else { + return null; + } + }, + dropDownValue: inductanceUnit, + onDropDownChanged: (value) { + setState(() { + inductanceUnit = value!; + calculateFrequency(); + }); + }, + dropDownList: inductanceDropDownList), + ), + Padding( + padding: const EdgeInsets.symmetric( + vertical: 9, + ), + child: InputFieldDropDown( + hintText: "Enter capacitance", + labelText: "Capacitance", + controller: capacitanceController, + onTextChanged: (text) { + setState(() { + capacitance = text; + calculateFrequency(); + }); + }, + validator: (text) {}, + dropDownValue: capacitanceUnit, + onDropDownChanged: (value) { + setState(() { + capacitanceUnit = value!; + calculateFrequency(); + }); + }, + dropDownList: capacitanceDropDownList), + ), + ], + ), + ), + ), + ), ), ); } diff --git a/lib/util/constants.dart b/lib/util/constants.dart index 5d7b930..9beb754 100644 --- a/lib/util/constants.dart +++ b/lib/util/constants.dart @@ -10,3 +10,21 @@ const lightCategoryTextStyle = TextStyle( fontFamily: "OpenSans", color: Colors.black54, ); + +const normalTextStyleOpenSans14 = TextStyle( + fontFamily: "OpenSans", + fontWeight: FontWeight.normal, + fontSize: 15, +); + +const biggerTextStyleOpenSans15 = TextStyle( + fontFamily: "OpenSans", + fontWeight: FontWeight.w500, + fontSize: 16, +); + +const lightBlueColor = Color(0xffe1efff); + +enum Units { DEFAULT, MILI, MICRO, NANO, PICO, KILO, MEGA, GIGA } + +const voltageUnitText = "V"; diff --git a/lib/util/conversion.dart b/lib/util/conversion.dart new file mode 100644 index 0000000..096defa --- /dev/null +++ b/lib/util/conversion.dart @@ -0,0 +1,41 @@ +import 'package:coiler_app/util/constants.dart'; + +class Converter { + static const Map unitsMap = { + Units.DEFAULT: 1.0, + Units.MILI: 0.001, + Units.MICRO: 0.000001, + Units.NANO: 0.000000001, + Units.PICO: 0.000000000001, + Units.KILO: 1000, + Units.MEGA: 1000000, + Units.GIGA: 1000000000, + }; + + double getCapMultiplier(Units unit) => unitsMap[unit]!; + + /// Function used to convert different units + /// [value] value to be converted + /// [from] from which unit we need to convert + /// [to] unit which we will convert to + /// + /// Example: + /// + /// ```dart + /// result = convertUnits(22, Units.MICRO, Units.NANO) -> 22000.0 + /// result = convertUnits(2, Units.DEFAULT, Units.MICRO) -> 2000000.0 + /// result = convertUnits(13.4, Units.PICO, Units.NANO) -> 0.0134 + /// ``` + /// + double convertUnits(dynamic value, Units from, Units to) { + double result = 0.0; + try { + var multiplier = getCapMultiplier(from) / getCapMultiplier(to); + double tempResult = value * multiplier; + result = tempResult; //double.parse(tempResult.toStringAsFixed(7)); + } catch (e) { + print(e); + } + return result; + } +} diff --git a/lib/util/list_constants.dart b/lib/util/list_constants.dart new file mode 100644 index 0000000..66c016f --- /dev/null +++ b/lib/util/list_constants.dart @@ -0,0 +1,59 @@ +import 'package:coiler_app/util/constants.dart'; +import 'package:flutter/material.dart'; + +const capacitanceDropDownList = [ + DropdownMenuItem( + child: Text("F"), + value: Units.DEFAULT, + ), + DropdownMenuItem( + child: Text("uF"), + value: Units.MICRO, + ), + DropdownMenuItem( + child: Text("nF"), + value: Units.NANO, + ), + DropdownMenuItem( + child: Text("pF"), + value: Units.PICO, + ), +]; + +const inductanceDropDownList = [ + DropdownMenuItem( + child: Text("H"), + value: Units.DEFAULT, + ), + DropdownMenuItem( + child: Text("mH"), + value: Units.MILI, + ), + DropdownMenuItem( + child: Text("uH"), + value: Units.MICRO, + ), + DropdownMenuItem( + child: Text("nH"), + value: Units.NANO, + ), +]; + +const frequencyDropDownList = [ + DropdownMenuItem( + child: Text("Hz"), + value: Units.DEFAULT, + ), + DropdownMenuItem( + child: Text("kHz"), + value: Units.KILO, + ), + DropdownMenuItem( + child: Text("MHz"), + value: Units.MEGA, + ), + DropdownMenuItem( + child: Text("GHz"), + value: Units.GIGA, + ), +]; diff --git a/lib/widgets/border_container.dart b/lib/widgets/border_container.dart new file mode 100644 index 0000000..49e8a3e --- /dev/null +++ b/lib/widgets/border_container.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; + +/// [backgroundImage] is image asset path which displays image in the background of the container with certain opacity. +/// +/// +class BorderContainer extends StatelessWidget { + const BorderContainer( + {Key? key, this.child, this.backgroundImage, this.elevated}) + : super(key: key); + + final Widget? child; + final String? backgroundImage; + final bool? elevated; + + static const List shadows = [ + BoxShadow( + color: Color(0xFFebebeb), + blurRadius: 12, + spreadRadius: 1, + offset: Offset(0, 3), + ), + ]; + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(9), + decoration: BoxDecoration( + color: Colors.white, + boxShadow: (elevated != null && elevated != false) ? shadows : [], + border: Border.all(color: Colors.black26), + borderRadius: BorderRadius.circular(16), + image: backgroundImage != null + ? DecorationImage( + opacity: 0.04, + fit: BoxFit.contain, + image: AssetImage(backgroundImage ?? ""), + ) + : null, + ), + child: child, + ); + } +} diff --git a/lib/widgets/input_field.dart b/lib/widgets/input_field.dart new file mode 100644 index 0000000..e665bc5 --- /dev/null +++ b/lib/widgets/input_field.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class InputField extends StatelessWidget { + const InputField( + {Key? key, + required this.controller, + required this.onTextChanged, + required this.validator, + this.inputType = const TextInputType.numberWithOptions(decimal: true), + this.hintText = "", + this.labelText = "", + this.maxLength, + required this.unitText, + required this.inputFormatter}) + : super(key: key); + + final TextEditingController controller; + final Function(String? text) validator; + final Function(dynamic value) onTextChanged; + final List inputFormatter; + final TextInputType inputType; + final String hintText; + final String labelText; + final String unitText; + final int? maxLength; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only( + top: 12, + ), + child: TextFormField( + autovalidateMode: AutovalidateMode.onUserInteraction, + onChanged: (value) => onTextChanged(value), + validator: (text) => validator(text), + controller: controller, + keyboardType: inputType, + maxLines: 1, + maxLength: maxLength, + inputFormatters: inputFormatter, + decoration: InputDecoration( + suffixIcon: Padding( + padding: const EdgeInsets.only( + right: 9, + ), + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 3, + horizontal: 9, + ), + decoration: BoxDecoration( + color: const Color(0xffe1efff), + borderRadius: BorderRadius.circular(9), + ), + child: Align( + alignment: Alignment.center, + widthFactor: 1, + child: Text( + unitText, + textAlign: TextAlign.center, + maxLines: 1, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontFamily: "OpenSans", + ), + ), + ), + ), + ), + hintText: hintText, + labelText: labelText, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(9), + ), + ), + ), + ); + } +} diff --git a/lib/widgets/input_field_dropdown.dart b/lib/widgets/input_field_dropdown.dart new file mode 100644 index 0000000..b4ab1bd --- /dev/null +++ b/lib/widgets/input_field_dropdown.dart @@ -0,0 +1,74 @@ +import 'package:coiler_app/util/constants.dart'; +import 'package:flutter/material.dart'; + +class InputFieldDropDown extends StatelessWidget { + const InputFieldDropDown({ + Key? key, + required this.controller, + required this.onTextChanged, + required this.validator, + this.inputType = const TextInputType.numberWithOptions(decimal: true), + this.hintText = "", + this.labelText = "", + required this.dropDownValue, + required this.onDropDownChanged, + required this.dropDownList, + }) : super(key: key); + + final TextEditingController controller; + final Function(String? text) validator; + final Function(dynamic value) onTextChanged; + final Function(Units? unit) onDropDownChanged; + final TextInputType inputType; + final String hintText; + final String labelText; + final Units dropDownValue; + final List> dropDownList; + + @override + Widget build(BuildContext context) { + return TextFormField( + autovalidateMode: AutovalidateMode.onUserInteraction, + onChanged: (value) => onTextChanged(value), + validator: (text) => validator(text), + controller: controller, + keyboardType: inputType, + decoration: InputDecoration( + suffixIcon: Padding( + padding: const EdgeInsets.only( + right: 9, + ), + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 3, + horizontal: 12, + ), + decoration: BoxDecoration( + color: const Color(0xffe1efff), + borderRadius: BorderRadius.circular(9), + ), + child: Align( + alignment: Alignment.centerRight, + widthFactor: 1, + child: DropdownButton( + borderRadius: BorderRadius.circular(9), + value: dropDownValue, + style: + normalTextStyleOpenSans14.copyWith(color: Colors.black87), + underline: Container(), + items: dropDownList, + onChanged: (value) => onDropDownChanged(value), + isDense: true, + ), + ), + ), + ), + hintText: hintText, + labelText: labelText, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(9), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 7e78bae..5576fde 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,27 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "31.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "2.8.0" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" async: dependency: transitive description: @@ -29,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.5" clock: dependency: transitive description: @@ -43,6 +71,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + coverage: + dependency: transitive + description: + name: coverage + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" cupertino_icons: dependency: "direct main" description: @@ -57,6 +106,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" flutter: dependency: "direct main" description: flutter @@ -74,6 +130,48 @@ packages: description: flutter source: sdk version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.4" lints: dependency: transitive description: @@ -81,6 +179,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" matcher: dependency: transitive description: @@ -102,6 +207,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.7.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + node_preamble: + dependency: transitive + description: + name: node_preamble + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" path: dependency: transitive description: @@ -109,11 +235,67 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + shelf_static: + dependency: transitive + description: + name: shelf_static + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + source_maps: + dependency: transitive + description: + name: source_maps + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.10" source_span: dependency: transitive description: @@ -149,6 +331,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + test: + dependency: "direct main" + description: + name: test + url: "https://pub.dartlang.org" + source: hosted + version: "1.19.5" test_api: dependency: transitive description: @@ -156,6 +345,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.8" + test_core: + dependency: transitive + description: + name: test_core + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.9" typed_data: dependency: transitive description: @@ -170,5 +366,40 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + vm_service: + dependency: transitive + description: + name: vm_service + url: "https://pub.dartlang.org" + source: hosted + version: "7.5.0" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" sdks: dart: ">=2.16.1 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index b64ce00..6948f15 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,6 +34,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + test: dev_dependencies: flutter_test: