From 4a42dc49d95cb5aee05e0b64ec85bd21604b3e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Thu, 8 Jan 2026 18:47:48 +0100 Subject: [PATCH 1/9] Primer intento docker --- Dockerfile | 18 ++++++++++++++++++ docker-compose.yml | 12 ++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..617e364 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +# Use the official Flutter SDK image +FROM cirrusci/flutter:latest + +# Set the working directory +WORKDIR /app + +# Copy the pubspec.yaml and install dependencies +COPY pubspec.yaml pubspec.lock ./ +RUN flutter pub get + +# Copy the rest of the application code +COPY . . + +# Build the Flutter app for Android +RUN flutter build apk --release + +# Use the following entrypoint if you want to run the app in a container +# ENTRYPOINT ["flutter", "run", "--release"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8a9b978 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3.8' + +services: + flutter: + build: + context: . + dockerfile: Dockerfile + volumes: + - .:/app # Link the current directory to /app in the container + environment: + - FLUTTER_FLAVOR=prod # Example environment variable, adjust as needed + command: flutter build apk --release # You can run any Flutter command here From a0d9a34182b0b7486ffca673d310f81969cbecb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Fri, 9 Jan 2026 09:28:28 +0100 Subject: [PATCH 2/9] Va medianamente con podman, no consigo que se creeen muchos containers --- Dockerfile | 27 ++++++++++++++++----------- Makefile | 19 +++++++++++++++++++ docker-compose.yml | 3 ++- firejail-warp-terminal.profile | 11 ----------- pubspec.lock | 4 ++-- warp-terminal.sh | 1 - 6 files changed, 39 insertions(+), 26 deletions(-) create mode 100644 Makefile delete mode 100644 firejail-warp-terminal.profile delete mode 100755 warp-terminal.sh diff --git a/Dockerfile b/Dockerfile index 617e364..89636bc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,23 @@ # Use the official Flutter SDK image -FROM cirrusci/flutter:latest +FROM ghcr.io/cirruslabs/flutter:stable + +# Install cmake, ninja, clang, pkg-config for flutter linux +RUN apt-get update && apt-get install -y cmake ninja-build clang pkg-config libgtk-3-dev liblzma-dev -# Set the working directory WORKDIR /app -# Copy the pubspec.yaml and install dependencies +# Configure cache directories +ENV PUB_CACHE=/cache/pub-cache +ENV GRADLE_USER_HOME=/cache/gradle-cache +RUN mkdir -p $PUB_CACHE $GRADLE_USER_HOME + +# Copy pubspec files and get dependencies +# This step is separated to leverage Docker layer caching +# REMEMBER: buld application with Makefile, it builds docker image first COPY pubspec.yaml pubspec.lock ./ RUN flutter pub get -# Copy the rest of the application code -COPY . . - -# Build the Flutter app for Android -RUN flutter build apk --release - -# Use the following entrypoint if you want to run the app in a container -# ENTRYPOINT ["flutter", "run", "--release"] +# Copy the rest of the application code and build +# Commented out to avoid building the app during image creation, this will be handled externally by makefile +# COPY . . +# RUN flutter build apk --release diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c6feabb --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ + +build-podman: + podman-compose build + +clean-podman: build-podman + podman-compose run --entrypoint "flutter clean" flutter + + +build-android-release-podman: build-podman + podman-compose run --entrypoint "flutter build apk --release" flutter + +build-linux-debug-podman: build-podman + podman-compose run --entrypoint "flutter build linux" flutter + +run-linux-debug: build-linux-debug-podman + build/linux/x64/debug/bundle/d4rt_formulas + +run-web-release-podman: build-web-release-podman + podman-compose run --entrypoint "cd build/web && python3 -m http.server 8080" flutter diff --git a/docker-compose.yml b/docker-compose.yml index 8a9b978..cd4fe81 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,8 +5,9 @@ services: build: context: . dockerfile: Dockerfile + image: d4rt-formulas-builder volumes: + - ./docker/cache:/cache - .:/app # Link the current directory to /app in the container environment: - FLUTTER_FLAVOR=prod # Example environment variable, adjust as needed - command: flutter build apk --release # You can run any Flutter command here diff --git a/firejail-warp-terminal.profile b/firejail-warp-terminal.profile deleted file mode 100644 index 5406c7b..0000000 --- a/firejail-warp-terminal.profile +++ /dev/null @@ -1,11 +0,0 @@ -# launch as: firejail --profile=firejail-warp-terminal.profile /opt/warpdotdev/warp-terminal/warp -private /home/alvaro/repos/d4rt_formulas/ -blacklist /datos-1T -blacklist /datos-luks/ -blacklist /media - -# net none # disable network -# noroot # don't run as root -caps.drop all # drop Linux capabilities -# seccomp # enable syscall filtering -First version of a formula widget \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 9ee6b4b..375e3d9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -356,10 +356,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: diff --git a/warp-terminal.sh b/warp-terminal.sh deleted file mode 100755 index 8471c2f..0000000 --- a/warp-terminal.sh +++ /dev/null @@ -1 +0,0 @@ -firejail --profile=firejail-warp-terminal.profile warp-terminal From c1d76ed496d5ff97a1fff0fc37c8e2277fe256ae Mon Sep 17 00:00:00 2001 From: "alvaro@a37" Date: Fri, 9 Jan 2026 11:45:11 +0100 Subject: [PATCH 3/9] selinux y podman --- Makefile | 4 ++-- README.md | 10 +++------- docker-compose.yml | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index c6feabb..57a924d 100644 --- a/Makefile +++ b/Makefile @@ -10,10 +10,10 @@ build-android-release-podman: build-podman podman-compose run --entrypoint "flutter build apk --release" flutter build-linux-debug-podman: build-podman - podman-compose run --entrypoint "flutter build linux" flutter + podman-compose run --entrypoint "flutter build linux --debug" flutter run-linux-debug: build-linux-debug-podman build/linux/x64/debug/bundle/d4rt_formulas run-web-release-podman: build-web-release-podman - podman-compose run --entrypoint "cd build/web && python3 -m http.server 8080" flutter + cd build/web && python3 -m http.server 8080 diff --git a/README.md b/README.md index 00d6931..fda9c0d 100644 --- a/README.md +++ b/README.md @@ -123,15 +123,11 @@ Each formula includes: - **Images** - Visual diagrams, graphs, or illustrations - **Examples** - Sample calculations and use cases -## Project Structure - -- `bin/` - Main executable and entry point -- `lib/` - Core library code and formula engine -- `test/` - Unit tests and formula validation tests - ## Getting Started -[Installation and usage instructions to be added] +This project uses `flutter`, so a valid installation is needed in order to build it. + +For convenience, a containerized build is provided. It is based on `podman` and `podman-compose`. See [Makefile](Makefile) for details. ## Contributing diff --git a/docker-compose.yml b/docker-compose.yml index cd4fe81..73feed0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ services: dockerfile: Dockerfile image: d4rt-formulas-builder volumes: - - ./docker/cache:/cache - - .:/app # Link the current directory to /app in the container + - ./docker/cache:/cache:z + - .:/app:z # Link the current directory to /app in the container environment: - FLUTTER_FLAVOR=prod # Example environment variable, adjust as needed From f0db9c880e05676f55dace8b6d4bca15d108789f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Fri, 9 Jan 2026 13:57:44 +0100 Subject: [PATCH 4/9] =?UTF-8?q?funci=C3=B3n=20makefile,=20mejores=20depend?= =?UTF-8?q?encias=20makefile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 6 ++---- Makefile | 14 +++++++++----- docker-compose.yml | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 89636bc..4552cb9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,10 +12,8 @@ ENV GRADLE_USER_HOME=/cache/gradle-cache RUN mkdir -p $PUB_CACHE $GRADLE_USER_HOME # Copy pubspec files and get dependencies -# This step is separated to leverage Docker layer caching -# REMEMBER: buld application with Makefile, it builds docker image first -COPY pubspec.yaml pubspec.lock ./ -RUN flutter pub get +# COPY pubspec.yaml pubspec.lock ./ +# RUN flutter pub get # Copy the rest of the application code and build # Commented out to avoid building the app during image creation, this will be handled externally by makefile diff --git a/Makefile b/Makefile index 57a924d..ae3537e 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,20 @@ +flutter-container-exec = podman-compose run --entrypoint "$(1)" flutter + build-podman: podman-compose build clean-podman: build-podman - podman-compose run --entrypoint "flutter clean" flutter + $(call flutter-container-exec, flutter clean) +pub-get-podman: build-podman + $(call flutter-container-exec, flutter pub get) -build-android-release-podman: build-podman - podman-compose run --entrypoint "flutter build apk --release" flutter +build-android-release-podman: pub-get-podman + $(call flutter-container-exec, flutter build apk --release) -build-linux-debug-podman: build-podman - podman-compose run --entrypoint "flutter build linux --debug" flutter +build-linux-debug-podman: pub-get-podman + $(call flutter-container-exec, flutter build linux --debug) run-linux-debug: build-linux-debug-podman build/linux/x64/debug/bundle/d4rt_formulas diff --git a/docker-compose.yml b/docker-compose.yml index 73feed0..1dcbe96 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ services: dockerfile: Dockerfile image: d4rt-formulas-builder volumes: - - ./docker/cache:/cache:z + - ./.build-container-cache:/cache:z - .:/app:z # Link the current directory to /app in the container environment: - FLUTTER_FLAVOR=prod # Example environment variable, adjust as needed From 49962b95d672169b05f8f40979d01ff2304bc19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Sat, 10 Jan 2026 13:59:55 +0100 Subject: [PATCH 5/9] quito algunas versiones obligatorias --- Makefile | 2 + README.md | 2 + pubspec.lock | 706 --------------------------------------------------- pubspec.yaml | 4 +- 4 files changed, 6 insertions(+), 708 deletions(-) delete mode 100644 pubspec.lock diff --git a/Makefile b/Makefile index ae3537e..613c3cb 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ flutter-container-exec = podman-compose run --entrypoint "$(1)" flutter +all: clean-podman build-linux-debug-podman build-linux-debug-podman + build-podman: podman-compose build diff --git a/README.md b/README.md index fda9c0d..7c627a7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +https://github.com/Shahxad-Akram/flutter_tex/blob/master/example/lib/tex_view_markdown_example.dart + # Math Formulae Manager A comprehensive command-line application for managing and computing mathematical formulas across various disciplines including mathematics, physics, medicine, and engineering. diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index 375e3d9..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,706 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f - url: "https://pub.dev" - source: hosted - version: "85.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - sha256: "974859dc0ff5f37bc4313244b3218c791810d03ab3470a579580279ba971a48d" - url: "https://pub.dev" - source: hosted - version: "7.7.1" - args: - dependency: transitive - description: - name: args - sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 - url: "https://pub.dev" - source: hosted - version: "2.7.0" - async: - dependency: transitive - description: - name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" - url: "https://pub.dev" - source: hosted - version: "2.13.0" - autotrie: - dependency: transitive - description: - name: autotrie - sha256: "55da6faefb53cfcb0abb2f2ca8636123fb40e35286bb57440d2cf467568188f8" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - characters: - dependency: transitive - description: - name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - charcode: - dependency: transitive - description: - name: charcode - sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a - url: "https://pub.dev" - source: hosted - version: "1.4.0" - cli_config: - dependency: transitive - description: - name: cli_config - sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec - url: "https://pub.dev" - source: hosted - version: "0.2.0" - clock: - dependency: transitive - description: - name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.dev" - source: hosted - version: "1.1.2" - collection: - dependency: "direct main" - description: - name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.dev" - source: hosted - version: "1.19.1" - convert: - dependency: transitive - description: - name: convert - sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 - url: "https://pub.dev" - source: hosted - version: "3.1.2" - coverage: - dependency: transitive - description: - name: coverage - sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d" - url: "https://pub.dev" - source: hosted - version: "1.15.0" - crypto: - dependency: transitive - description: - name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://pub.dev" - source: hosted - version: "3.0.6" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.dev" - source: hosted - version: "1.0.8" - d4rt: - dependency: "direct main" - description: - name: d4rt - sha256: "1eb626145e2ed97332f9e6e842e626f973d3969ce30e2794efb4744bd8aeba63" - url: "https://pub.dev" - source: hosted - version: "0.1.7" - equatable: - dependency: transitive - description: - name: equatable - sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" - url: "https://pub.dev" - source: hosted - version: "2.0.7" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" - url: "https://pub.dev" - source: hosted - version: "1.3.3" - file: - dependency: transitive - description: - name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.dev" - source: hosted - version: "7.0.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_code_editor: - dependency: "direct main" - description: - name: flutter_code_editor - sha256: "9af48ba8e3558b6ea4bb98b84c5eb1649702acf53e61a84d88383eeb79b239b0" - url: "https://pub.dev" - source: hosted - version: "0.3.5" - flutter_d4rt: - dependency: "direct main" - description: - name: flutter_d4rt - sha256: "7ab9d3f91de5c10db115ccab1d9b1588946f744850f5bacc243cfc9041dd0a4c" - url: "https://pub.dev" - source: hosted - version: "0.0.5" - flutter_highlight: - dependency: transitive - description: - name: flutter_highlight - sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c" - url: "https://pub.dev" - source: hosted - version: "0.7.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" - url: "https://pub.dev" - source: hosted - version: "6.0.0" - flutter_markdown: - dependency: "direct main" - description: - name: flutter_markdown - sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27" - url: "https://pub.dev" - source: hosted - version: "0.7.7+1" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 - url: "https://pub.dev" - source: hosted - version: "4.0.0" - glob: - dependency: transitive - description: - name: glob - sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de - url: "https://pub.dev" - source: hosted - version: "2.1.3" - highlight: - dependency: transitive - description: - name: highlight - sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21" - url: "https://pub.dev" - source: hosted - version: "0.7.0" - hive: - dependency: transitive - description: - name: hive - sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" - url: "https://pub.dev" - source: hosted - version: "2.2.3" - http: - dependency: transitive - description: - name: http - sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 - url: "https://pub.dev" - source: hosted - version: "1.5.0" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 - url: "https://pub.dev" - source: hosted - version: "3.2.2" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://pub.dev" - source: hosted - version: "4.1.2" - io: - dependency: transitive - description: - name: io - sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b - url: "https://pub.dev" - source: hosted - version: "1.0.5" - js: - dependency: transitive - description: - name: js - sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" - url: "https://pub.dev" - source: hosted - version: "0.7.2" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" - url: "https://pub.dev" - source: hosted - version: "11.0.2" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" - url: "https://pub.dev" - source: hosted - version: "3.0.10" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - linked_scroll_controller: - dependency: transitive - description: - name: linked_scroll_controller - sha256: e6020062bcf4ffc907ee7fd090fa971e65d8dfaac3c62baf601a3ced0b37986a - url: "https://pub.dev" - source: hosted - version: "0.2.0" - lints: - dependency: transitive - description: - name: lints - sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 - url: "https://pub.dev" - source: hosted - version: "6.0.0" - logging: - dependency: transitive - description: - name: logging - sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 - url: "https://pub.dev" - source: hosted - version: "1.3.0" - markdown: - dependency: transitive - description: - name: markdown - sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1" - url: "https://pub.dev" - source: hosted - version: "7.3.0" - matcher: - dependency: transitive - description: - name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://pub.dev" - source: hosted - version: "0.12.17" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" - source: hosted - version: "0.11.1" - meta: - dependency: transitive - description: - name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" - url: "https://pub.dev" - source: hosted - version: "1.17.0" - mime: - dependency: transitive - description: - name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - mocktail: - dependency: transitive - description: - name: mocktail - sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - node_preamble: - dependency: transitive - description: - name: node_preamble - sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - package_config: - dependency: transitive - description: - name: package_config - sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc - url: "https://pub.dev" - source: hosted - version: "2.2.0" - path: - dependency: transitive - description: - name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" - source: hosted - version: "2.1.8" - pool: - dependency: transitive - description: - name: pool - sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" - url: "https://pub.dev" - source: hosted - version: "1.5.2" - pub_semver: - dependency: transitive - description: - name: pub_semver - sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" - url: "https://pub.dev" - source: hosted - version: "2.2.0" - resource_portable: - dependency: "direct main" - description: - name: resource_portable - sha256: "8ffa33b0769645e26d82c8f4e79adde3dd34b9e0bba981166d4e3798f39cffd9" - url: "https://pub.dev" - source: hosted - version: "3.1.2" - scrollable_positioned_list: - dependency: transitive - description: - name: scrollable_positioned_list - sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287" - url: "https://pub.dev" - source: hosted - version: "0.3.8" - shelf: - dependency: transitive - description: - name: shelf - sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 - url: "https://pub.dev" - source: hosted - version: "1.4.2" - shelf_packages_handler: - dependency: transitive - description: - name: shelf_packages_handler - sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - shelf_static: - dependency: transitive - description: - name: shelf_static - sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 - url: "https://pub.dev" - source: hosted - version: "1.1.3" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b - url: "https://pub.dev" - source: hosted - version: "2.1.2" - source_maps: - dependency: transitive - description: - name: source_maps - sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" - url: "https://pub.dev" - source: hosted - version: "0.10.13" - source_span: - dependency: transitive - description: - name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://pub.dev" - source: hosted - version: "1.10.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.dev" - source: hosted - version: "1.12.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.dev" - source: hosted - version: "1.4.1" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.dev" - source: hosted - version: "1.2.2" - test: - dependency: "direct dev" - description: - name: test - sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7" - url: "https://pub.dev" - source: hosted - version: "1.26.3" - test_api: - dependency: transitive - description: - name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 - url: "https://pub.dev" - source: hosted - version: "0.7.7" - test_core: - dependency: transitive - description: - name: test_core - sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0" - url: "https://pub.dev" - source: hosted - version: "0.6.12" - tuple: - dependency: transitive - description: - name: tuple - sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 - url: "https://pub.dev" - source: hosted - version: "2.0.2" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - url_launcher: - dependency: transitive - description: - name: url_launcher - sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 - url: "https://pub.dev" - source: hosted - version: "6.3.2" - url_launcher_android: - dependency: transitive - description: - name: url_launcher_android - sha256: "5c8b6c2d89a78f5a1cca70a73d9d5f86c701b36b42f9c9dac7bad592113c28e9" - url: "https://pub.dev" - source: hosted - version: "6.3.24" - url_launcher_ios: - dependency: transitive - description: - name: url_launcher_ios - sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 - url: "https://pub.dev" - source: hosted - version: "6.3.4" - url_launcher_linux: - dependency: transitive - description: - name: url_launcher_linux - sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f - url: "https://pub.dev" - source: hosted - version: "3.2.3" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" - url: "https://pub.dev" - source: hosted - version: "2.3.2" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - url_launcher_windows: - dependency: transitive - description: - name: url_launcher_windows - sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" - url: "https://pub.dev" - source: hosted - version: "3.1.4" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b - url: "https://pub.dev" - source: hosted - version: "2.2.0" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" - url: "https://pub.dev" - source: hosted - version: "15.0.2" - watcher: - dependency: transitive - description: - name: watcher - sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a" - url: "https://pub.dev" - source: hosted - version: "1.1.4" - web: - dependency: transitive - description: - name: web - sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - web_socket: - dependency: transitive - description: - name: web_socket - sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 - url: "https://pub.dev" - source: hosted - version: "3.0.3" - webkit_inspection_protocol: - dependency: transitive - description: - name: webkit_inspection_protocol - sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" - url: "https://pub.dev" - source: hosted - version: "1.2.1" - yaml: - dependency: transitive - description: - name: yaml - sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce - url: "https://pub.dev" - source: hosted - version: "3.1.3" -sdks: - dart: ">=3.9.0 <4.0.0" - flutter: ">=3.35.0" diff --git a/pubspec.yaml b/pubspec.yaml index b314177..7a0cea1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,8 +50,8 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^6.0.0 - test: ^1.26.3 + flutter_lints: + test: # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec From 76769973f33e49cb76aefbbe750d1ac372066961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Wed, 21 Jan 2026 08:49:56 +0100 Subject: [PATCH 6/9] can't make valiation on each user interaction --- .../formulas}/formulas.d4rt | 0 .../units/angle.d4rt.units | 0 .../defaults => assets}/units/area.d4rt.units | 0 .../units/distance.d4rt.units | 0 .../units/energy.d4rt.units | 0 .../units/force.d4rt.units | 0 .../defaults => assets}/units/mass.d4rt.units | 0 .../units/pressure.d4rt.units | 0 assets/units/scalar.d4rt.units | 3 + .../units/temperature.d4rt.units | 0 .../defaults => assets}/units/time.d4rt.units | 0 .../units/velocity.d4rt.units | 0 lib/ai/formula_screen.dart | 93 ++++++++------- lib/corpus.dart | 6 +- lib/defaults/default_corpus.dart | 38 ++++--- lib/defaults/units/scalar.d4rt.units | 3 - lib/formula_evaluator.dart | 4 +- lib/formula_models.dart | 18 +-- lib/main.dart | 1 + pubspec.yaml | 3 + test/d4rt_test.dart | 2 +- test/dart_test.dart | 2 +- test/formula_evaluator_test.dart | 107 ++++++++++++++++++ 23 files changed, 198 insertions(+), 82 deletions(-) rename {lib/defaults => assets/formulas}/formulas.d4rt (100%) rename {lib/defaults => assets}/units/angle.d4rt.units (100%) rename {lib/defaults => assets}/units/area.d4rt.units (100%) rename {lib/defaults => assets}/units/distance.d4rt.units (100%) rename {lib/defaults => assets}/units/energy.d4rt.units (100%) rename {lib/defaults => assets}/units/force.d4rt.units (100%) rename {lib/defaults => assets}/units/mass.d4rt.units (100%) rename {lib/defaults => assets}/units/pressure.d4rt.units (100%) create mode 100644 assets/units/scalar.d4rt.units rename {lib/defaults => assets}/units/temperature.d4rt.units (100%) rename {lib/defaults => assets}/units/time.d4rt.units (100%) rename {lib/defaults => assets}/units/velocity.d4rt.units (100%) delete mode 100644 lib/defaults/units/scalar.d4rt.units diff --git a/lib/defaults/formulas.d4rt b/assets/formulas/formulas.d4rt similarity index 100% rename from lib/defaults/formulas.d4rt rename to assets/formulas/formulas.d4rt diff --git a/lib/defaults/units/angle.d4rt.units b/assets/units/angle.d4rt.units similarity index 100% rename from lib/defaults/units/angle.d4rt.units rename to assets/units/angle.d4rt.units diff --git a/lib/defaults/units/area.d4rt.units b/assets/units/area.d4rt.units similarity index 100% rename from lib/defaults/units/area.d4rt.units rename to assets/units/area.d4rt.units diff --git a/lib/defaults/units/distance.d4rt.units b/assets/units/distance.d4rt.units similarity index 100% rename from lib/defaults/units/distance.d4rt.units rename to assets/units/distance.d4rt.units diff --git a/lib/defaults/units/energy.d4rt.units b/assets/units/energy.d4rt.units similarity index 100% rename from lib/defaults/units/energy.d4rt.units rename to assets/units/energy.d4rt.units diff --git a/lib/defaults/units/force.d4rt.units b/assets/units/force.d4rt.units similarity index 100% rename from lib/defaults/units/force.d4rt.units rename to assets/units/force.d4rt.units diff --git a/lib/defaults/units/mass.d4rt.units b/assets/units/mass.d4rt.units similarity index 100% rename from lib/defaults/units/mass.d4rt.units rename to assets/units/mass.d4rt.units diff --git a/lib/defaults/units/pressure.d4rt.units b/assets/units/pressure.d4rt.units similarity index 100% rename from lib/defaults/units/pressure.d4rt.units rename to assets/units/pressure.d4rt.units diff --git a/assets/units/scalar.d4rt.units b/assets/units/scalar.d4rt.units new file mode 100644 index 0000000..0533d87 --- /dev/null +++ b/assets/units/scalar.d4rt.units @@ -0,0 +1,3 @@ +[ + {"name": "scalar", "symbol": "", "isBase": true}, +] \ No newline at end of file diff --git a/lib/defaults/units/temperature.d4rt.units b/assets/units/temperature.d4rt.units similarity index 100% rename from lib/defaults/units/temperature.d4rt.units rename to assets/units/temperature.d4rt.units diff --git a/lib/defaults/units/time.d4rt.units b/assets/units/time.d4rt.units similarity index 100% rename from lib/defaults/units/time.d4rt.units rename to assets/units/time.d4rt.units diff --git a/lib/defaults/units/velocity.d4rt.units b/assets/units/velocity.d4rt.units similarity index 100% rename from lib/defaults/units/velocity.d4rt.units rename to assets/units/velocity.d4rt.units diff --git a/lib/ai/formula_screen.dart b/lib/ai/formula_screen.dart index 7b12262..4039f5a 100644 --- a/lib/ai/formula_screen.dart +++ b/lib/ai/formula_screen.dart @@ -1,6 +1,4 @@ - import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import '../formula_models.dart'; import '../formula_evaluator.dart'; @@ -11,11 +9,7 @@ class FormulaScreen extends StatefulWidget { final Formula formula; final Corpus corpus; - const FormulaScreen({ - super.key, - required this.formula, - required this.corpus, - }); + const FormulaScreen({super.key, required this.formula, required this.corpus}); @override State createState() => _FormulaScreenState(); @@ -24,7 +18,7 @@ class FormulaScreen extends StatefulWidget { //// Start of D4rtEditingController class //// class D4rtEditingController extends TextEditingController { String? _lastError; - + String _text = ""; String? get lastError => _lastError; FormulaResult? _lastValue; @@ -46,7 +40,6 @@ class D4rtEditingController extends TextEditingController { get d4rtValue => _lastValue; - @override set text(String newText) { super.text = newText; validate(); @@ -97,27 +90,37 @@ class _FormulaScreenState extends State { final inputValues = {}; for (final input in widget.formula.input) { final controller = _inputControllers[input.name]!; - if( controller.d4rtValue == null ){ - throw FormulaEvaluationException( "Field ${input.name} is invalid" ); + if (controller.d4rtValue == null) { + //throw FormulaEvaluationException("Field ${input.name} is invalid"); + _result = ""; + return; } - final value = controller.d4rtValue.value; - // Convert input to base unit if needed - // Always convert from dropdown unit to variable's base unit - late final convertedValue; - if( value is Number && input.unit != null ) { - convertedValue = widget.corpus.convert( - value, - _selectedUnits[input.name]!, - input.unit as String, - ); - } - else{ - convertedValue = value; + late final dynamic convertedValue; + + switch (controller.d4rtValue) { + case NumberResult nr: + // Convert input to base unit if needed + // Always convert from dropdown unit to variable's base unit + if (input.unit != null) { + convertedValue = widget.corpus.convert( + nr.value, + _selectedUnits[input.name]!, + input.unit as String, + ); + } else { + convertedValue = nr.value; + } + + case StringResult sr: + convertedValue = sr.value; + default: + throw FormulaEvaluationException( + "Field ${input.name} has unsupported type ${controller.d4rtValue!.runtimeType}", + ); } inputValues[input.name] = convertedValue; - } final evaluator = FormulaEvaluator(); @@ -125,14 +128,11 @@ class _FormulaScreenState extends State { // Convert output to selected unit if needed String? unit = widget.formula.output.unit; - if( unit != null ) { - _result = widget.corpus.convert( - result, - unit, - _selectedOutputUnit!, - ).toStringAsFixed(2); - } - else{ + if (unit != null) { + _result = widget.corpus + .convert(result, unit, _selectedOutputUnit!) + .toStringAsFixed(2); + } else { _result = result; } @@ -142,7 +142,7 @@ class _FormulaScreenState extends State { } catch (e, stack) { debugPrint('Formula evaluation error: $e'); debugPrint('Stack trace: $stack'); - + ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Error: ${e.toString()}\n${stack.toString()}'), @@ -155,9 +155,7 @@ class _FormulaScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.formula.name), - ), + appBar: AppBar(title: Text(widget.formula.name)), body: Form( key: _formKey, child: Padding( @@ -176,7 +174,7 @@ class _FormulaScreenState extends State { } Widget _buildDescriptionSection() { - if (widget.formula.description == null || + if (widget.formula.description == null || widget.formula.description!.isEmpty) { return const SizedBox.shrink(); } @@ -186,9 +184,9 @@ class _FormulaScreenState extends State { children: [ Text( 'Description', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.bold, - ), + style: Theme.of( + context, + ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Container( @@ -213,9 +211,9 @@ class _FormulaScreenState extends State { children: [ Text( 'Input Variables', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.bold, - ), + style: Theme.of( + context, + ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 8), ...widget.formula.input.map((variable) => _buildVariableRow(variable)), @@ -229,9 +227,9 @@ class _FormulaScreenState extends State { children: [ Text( 'Result', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.bold, - ), + style: Theme.of( + context, + ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Row( @@ -286,6 +284,7 @@ class _FormulaScreenState extends State { decoration: const InputDecoration( border: UnderlineInputBorder(), ), + autovalidateMode: AutovalidateMode.always, validator: (value) { if (value == null || value.isEmpty) { return 'Required'; diff --git a/lib/corpus.dart b/lib/corpus.dart index 0710d8b..f6b37e9 100644 --- a/lib/corpus.dart +++ b/lib/corpus.dart @@ -73,7 +73,7 @@ class Corpus{ List unitsOfSameMagnitude(String? unit){ if( unit == null ){ - return ["unitless"]; + return ["scalar"]; } final base = getUnit(unit).baseUnit; return _baseToUnits[base] as List; @@ -90,7 +90,7 @@ class Corpus{ String _converterFromCodeStringAsExpression(Number x, String codeString) { final buffer = StringBuffer(); - buffer.writeln("final x = ${x};"); + buffer.writeln("final x = $x;"); buffer.writeln("main(){return $codeString;}"); final code = buffer.toString(); return code; @@ -98,7 +98,7 @@ class Corpus{ String _converterFromCodeStringAsStatement(Number x, String codeString) { final buffer = StringBuffer(); - buffer.writeln("final x = ${x};"); + buffer.writeln("final x = $x;"); buffer.writeln("main(){ $codeString; return x; }"); final code = buffer.toString(); return code; diff --git a/lib/defaults/default_corpus.dart b/lib/defaults/default_corpus.dart index d740ba8..af7f983 100644 --- a/lib/defaults/default_corpus.dart +++ b/lib/defaults/default_corpus.dart @@ -1,42 +1,48 @@ +import 'dart:async'; import 'dart:convert' show utf8; +import 'package:flutter/services.dart' show rootBundle; import 'package:resource_portable/resource_portable.dart' show Resource; import '../corpus.dart'; import '../formula_models.dart'; + Future createDefaultCorpus() async{ final corpus = Corpus(); + Future loadResourceAsString(String path) async { + return await rootBundle.loadString(path, cache: false); + } + + Future loadUnits() async { final unitResources = [ - "lib/defaults/units/angle.d4rt.units", - "lib/defaults/units/area.d4rt.units", - "lib/defaults/units/distance.d4rt.units", - "lib/defaults/units/energy.d4rt.units", - "lib/defaults/units/force.d4rt.units", - "lib/defaults/units/mass.d4rt.units", - "lib/defaults/units/pressure.d4rt.units", - "lib/defaults/units/scalar.d4rt.units", - "lib/defaults/units/temperature.d4rt.units", - "lib/defaults/units/time.d4rt.units", - "lib/defaults/units/velocity.d4rt.units", + "assets/units/angle.d4rt.units", + "assets/units/area.d4rt.units", + "assets/units/distance.d4rt.units", + "assets/units/energy.d4rt.units", + "assets/units/force.d4rt.units", + "assets/units/mass.d4rt.units", + "assets/units/pressure.d4rt.units", + "assets/units/scalar.d4rt.units", + "assets/units/temperature.d4rt.units", + "assets/units/time.d4rt.units", + "assets/units/velocity.d4rt.units", ]; for (final unitRes in unitResources) { - final resource = Resource(unitRes); - final literal = await resource.readAsString(encoding: utf8); + final literal = await loadResourceAsString(unitRes); final units = UnitSpec.fromArrayStringLiteral(literal); corpus.loadUnits(units); } } Future loadFormulas() async { - final formulaResources = ["lib/defaults/formulas.d4rt"]; + final formulaResources = ["assets/formulas/formulas.d4rt"]; for (final formRes in formulaResources) { - final resource = Resource(formRes); - final literal = await resource.readAsString(encoding: utf8); + final literal = await loadResourceAsString(formRes); final formulas = Formula.fromArrayStringLiteral(literal); corpus.loadFormulas(formulas); } diff --git a/lib/defaults/units/scalar.d4rt.units b/lib/defaults/units/scalar.d4rt.units deleted file mode 100644 index c314f66..0000000 --- a/lib/defaults/units/scalar.d4rt.units +++ /dev/null @@ -1,3 +0,0 @@ -[ - {"name": "scalar", "symbol": "", "isBase": true} -] \ No newline at end of file diff --git a/lib/formula_evaluator.dart b/lib/formula_evaluator.dart index 9a844b9..1f6d961 100644 --- a/lib/formula_evaluator.dart +++ b/lib/formula_evaluator.dart @@ -76,14 +76,14 @@ class FormulaEvaluator { final d4rtInterpreter = interpreter ?? createDefaultInterpreter(); prepareInterpreter(d4rtInterpreter); final d4rtCode = """ - ${d4rtImports} + $d4rtImports main() { late var result; result = $code; return result; }"""; - //print("evaluateExpression:\n$d4rtCode"); + print("evaluateExpression:\n$d4rtCode"); final result = d4rtInterpreter.execute(source: d4rtCode); switch ( result ){ case int value: diff --git a/lib/formula_models.dart b/lib/formula_models.dart index 05bb6a8..9a0c5f6 100644 --- a/lib/formula_models.dart +++ b/lib/formula_models.dart @@ -102,17 +102,17 @@ class UnitSpec { class VariableSpec { final String name; final String? unit; - final List? allowedValues; + final List? values; - VariableSpec({required this.name, this.unit, this.allowedValues}){ - final valuesValid = allowedValues != null && allowedValues?.isNotEmpty == true; + VariableSpec({required this.name, this.unit, this.values}){ + final valuesValid = values != null && values?.isNotEmpty == true; if( unit == null && !valuesValid ){ - throw new ArgumentError("$name: at least unit or allowedValues should be valid"); + throw ArgumentError("$name: at least unit or allowedValues should be valid"); } } @override - String toString() => 'var($name: $unit${allowedValues != null ? ' allowed: $allowedValues' : ''})'; + String toString() => 'var($name: $unit${values != null ? ' allowed: $values' : ''})'; @override bool operator ==(Object other) => @@ -121,10 +121,10 @@ class VariableSpec { runtimeType == other.runtimeType && unit == other.unit && name == other.name && - const DeepCollectionEquality().equals(allowedValues, other.allowedValues); + const DeepCollectionEquality().equals(values, other.values); @override - int get hashCode => Object.hash(unit, name, allowedValues != null ? const DeepCollectionEquality().hash(allowedValues!) : 0); + int get hashCode => Object.hash(unit, name, values != null ? const DeepCollectionEquality().hash(values!) : 0); } class Formula { @@ -146,7 +146,7 @@ class Formula { validate(); } - validate() { + void validate() { if (name.trim().isEmpty) { throw ArgumentError('Formula name cannot be empty'); } @@ -220,7 +220,7 @@ class Formula { return VariableSpec( name: name, unit: unit, - allowedValues: allowed?.toList(growable: false), + values: allowed?.toList(growable: false), ); } diff --git a/lib/main.dart b/lib/main.dart index f21f76c..0f44288 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,6 +6,7 @@ import 'corpus.dart'; import 'defaults/default_corpus.dart'; void main() { + WidgetsFlutterBinding.ensureInitialized(); runApp(MaterialApp( home: FutureBuilder( future: createDefaultCorpus(), diff --git a/pubspec.yaml b/pubspec.yaml index 7a0cea1..c143b38 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -68,6 +68,9 @@ flutter: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg + assets: + - assets/units/ + - assets/formulas/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images diff --git a/test/d4rt_test.dart b/test/d4rt_test.dart index db0aeb4..0e948a8 100644 --- a/test/d4rt_test.dart +++ b/test/d4rt_test.dart @@ -3,7 +3,7 @@ import 'package:d4rt/d4rt.dart'; import 'dart:math' as Math; -main(){ +void main(){ test('Access to Math', () { final completeSource = """ diff --git a/test/dart_test.dart b/test/dart_test.dart index 9777d46..9e78acc 100644 --- a/test/dart_test.dart +++ b/test/dart_test.dart @@ -3,7 +3,7 @@ import 'package:d4rt/d4rt.dart'; import 'dart:math' as Math; -main(){ +void main(){ test('for dart grammar tests', () { }); diff --git a/test/formula_evaluator_test.dart b/test/formula_evaluator_test.dart index 0b4c04d..7c553ce 100644 --- a/test/formula_evaluator_test.dart +++ b/test/formula_evaluator_test.dart @@ -208,5 +208,112 @@ void main() { expect(result, closeTo(9.8596, 0.0001)); }); }); + + group('APGAR Score', () { + test('evaluates APGAR score formula - Normal case', () { + final formula = Formula( + name: "Apgar Score", + description: "Newborn health assessment scoring system", + input: [ + VariableSpec(name: "HeartRate", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "Breathing", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "MuscleTone", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "Reflexes", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "SkinColor", values: ["hr1", "hr2", "hr3"]) + ], + output: VariableSpec(name: "Result", unit: "stringscalar"), + d4rtCode: """ + var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor; + var interpretation = switch (total) { + >= 7 => 'Normal', + 4-6 => 'Requires attention', + _ => 'Emergency care needed' + }; + Result = 'Score: \$total - \$interpretation'; + """, + ); + + // Test normal case (score 7-10) + final result = evaluator.evaluate(formula, { + 'HeartRate': 2, + 'Breathing': 2, + 'MuscleTone': 2, + 'Reflexes': 2, + 'SkinColor': 2 + }); + + expect(result, 'Score: 10 - Normal'); + }); + + test('evaluates APGAR score formula - Requires attention case', () { + final formula = Formula( + name: "Apgar Score", + description: "Newborn health assessment scoring system", + input: [ + VariableSpec(name: "HeartRate", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "Breathing", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "MuscleTone", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "Reflexes", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "SkinColor", values: ["hr1", "hr2", "hr3"]) + ], + output: VariableSpec(name: "Result", unit: "stringscalar"), + d4rtCode: """ + var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor; + var interpretation = switch (total) { + >= 7 => 'Normal', + 4-6 => 'Requires attention', + _ => 'Emergency care needed' + }; + Result = 'Score: \$total - \$interpretation'; + """, + ); + + // Test requires attention case (score 4-6) + final result = evaluator.evaluate(formula, { + 'HeartRate': 1, + 'Breathing': 1, + 'MuscleTone': 1, + 'Reflexes': 1, + 'SkinColor': 2 + }); + + expect(result, 'Score: 6 - Requires attention'); + }); + + test('evaluates APGAR score formula - Emergency case', () { + final formula = Formula( + name: "Apgar Score", + description: "Newborn health assessment scoring system", + input: [ + VariableSpec(name: "HeartRate", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "Breathing", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "MuscleTone", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "Reflexes", values: ["hr1", "hr2", "hr3"]), + VariableSpec(name: "SkinColor", values: ["hr1", "hr2", "hr3"]) + ], + output: VariableSpec(name: "Result", unit: "stringscalar"), + d4rtCode: """ + var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor; + var interpretation = switch (total) { + >= 7 => 'Normal', + 4-6 => 'Requires attention', + _ => 'Emergency care needed' + }; + Result = 'Score: \$total - \$interpretation'; + """, + ); + + // Test emergency case (score 0-3) + final result = evaluator.evaluate(formula, { + 'HeartRate': 0, + 'Breathing': 0, + 'MuscleTone': 1, + 'Reflexes': 0, + 'SkinColor': 1 + }); + + expect(result, 'Score: 2 - Emergency care needed'); + }); + }); }); } From fd5999d586fc5d635bd19c9bcf0b86e021582829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Sun, 25 Jan 2026 18:39:43 +0100 Subject: [PATCH 7/9] Better apgar formula --- assets/formulas/formulas.d4rt | 10 +++++----- lib/ai/formula_screen.dart | 8 +++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/assets/formulas/formulas.d4rt b/assets/formulas/formulas.d4rt index fafa242..b14639c 100644 --- a/assets/formulas/formulas.d4rt +++ b/assets/formulas/formulas.d4rt @@ -126,11 +126,11 @@ Where: "name": "Apgar Score", "description": "Newborn health assessment scoring system\n\nScores 0-2 for:\n1. Heart rate\n2. Breathing\n3. Muscle tone\n4. Reflexes\n5. Skin color\nTotal score 0-10", "input": [ - {"name": "HeartRate", "values": ["hr1", "hr2", "hr3"] }, - {"name": "Breathing", "values": ["hr1", "hr2", "hr3"] }, - {"name": "MuscleTone", "values": ["hr1", "hr2", "hr3"] }, - {"name": "Reflexes", "values": ["hr1", "hr2", "hr3"] }, - {"name": "SkinColor", "values": ["hr1", "hr2", "hr3"] } + {"name": "HeartRate", "values": ["Absent", "< 100 bpm>", "> 100 bpm"] }, + {"name": "Breathing", "values": ["Absent", "Weak, irregular", "Strong, robust cry"] }, + {"name": "MuscleTone", "values": ["None", "Some", "Flexed arms/leg, resists extension"] }, + {"name": "Reflexes", "values": ["No response", "Grimace on aggressive stimulation", "Cry on stimulation"] }, + {"name": "SkinColor", "values": ["Blue or pale", "Blue extremities, pink body", "Pink"] } ], "output": {"name": "Result", "unit": "scalar"}, "d4rtCode": """ diff --git a/lib/ai/formula_screen.dart b/lib/ai/formula_screen.dart index 4039f5a..eb91e75 100644 --- a/lib/ai/formula_screen.dart +++ b/lib/ai/formula_screen.dart @@ -15,14 +15,16 @@ class FormulaScreen extends StatefulWidget { State createState() => _FormulaScreenState(); } +// TODO: Create VariableWidget. Depending on VariableSpec.values, it can be a ValueDropdown or a D4rtEditingController +// The d4rtValue will be FormulaResult? + //// Start of D4rtEditingController class //// class D4rtEditingController extends TextEditingController { String? _lastError; - String _text = ""; String? get lastError => _lastError; FormulaResult? _lastValue; - D4rtEditingController({String? text}) : super(text: text); + D4rtEditingController({super.text}); bool validate() { try { @@ -38,7 +40,7 @@ class D4rtEditingController extends TextEditingController { } } - get d4rtValue => _lastValue; + FormulaResult? get d4rtValue => _lastValue; set text(String newText) { super.text = newText; From b2ffea801a216f227412a79c95b945219d9cc88a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Sun, 25 Jan 2026 19:03:57 +0100 Subject: [PATCH 8/9] formula works, mergin in main --- assets/formulas/formulas.d4rt | 15 +++-- lib/corpus.dart | 4 ++ lib/formula_evaluator.dart | 13 +++- pubspec.yaml | 2 +- test/formula_evaluator_test.dart | 107 ------------------------------- test/formula_models_test.dart | 36 +++++++++-- 6 files changed, 55 insertions(+), 122 deletions(-) diff --git a/assets/formulas/formulas.d4rt b/assets/formulas/formulas.d4rt index b14639c..a6dc9db 100644 --- a/assets/formulas/formulas.d4rt +++ b/assets/formulas/formulas.d4rt @@ -135,11 +135,16 @@ Where: "output": {"name": "Result", "unit": "scalar"}, "d4rtCode": """ var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor; - var interpretation = switch (total) { - >= 7 => 'Normal', - 4-6 => 'Requires attention', - _ => 'Emergency care needed' - }; + late var interpretation; + if( total < 4 ) { + interpretation = 'Critical condition'; + } + else if( total < 7 ){ + interpretation = 'Needs assistance'; + } + else { + interpretation = 'Normal'; + } Result = 'Score: \$total - \$interpretation'; """, "tags": ["medical", "pediatrics", "assessment"] diff --git a/lib/corpus.dart b/lib/corpus.dart index f6b37e9..7ad4f50 100644 --- a/lib/corpus.dart +++ b/lib/corpus.dart @@ -58,6 +58,10 @@ class Corpus{ return _allFormulas.values.toList(growable:false); } + Formula? getFormula(String name) { + return _allFormulas.get(name); + } + final Multimap _baseToUnits = Multimap.create(); final Map _allUnits = {}; diff --git a/lib/formula_evaluator.dart b/lib/formula_evaluator.dart index 1f6d961..acc978d 100644 --- a/lib/formula_evaluator.dart +++ b/lib/formula_evaluator.dart @@ -100,8 +100,17 @@ class FormulaEvaluator { dynamic evaluate(Formula formula, Map inputValues) { _validateInputValues(formula, inputValues); final completeSource = _buildCompleteSource(formula, inputValues); - final result = _interpreter.execute(source: completeSource); - return result; + try { + final result = _interpreter.execute(source: completeSource); + return result; + } + catch (e) { + print( "Error evaluating formula source:\n$completeSource" ); + throw FormulaEvaluationException( + 'Error evaluating formula "${formula.name}": $e', + e, + ); + } } void _validateInputValues(Formula formula, Map inputValues) { diff --git a/pubspec.yaml b/pubspec.yaml index c143b38..d70efdb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.8.1 + sdk: ^3.10.7 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions diff --git a/test/formula_evaluator_test.dart b/test/formula_evaluator_test.dart index 7c553ce..0b4c04d 100644 --- a/test/formula_evaluator_test.dart +++ b/test/formula_evaluator_test.dart @@ -208,112 +208,5 @@ void main() { expect(result, closeTo(9.8596, 0.0001)); }); }); - - group('APGAR Score', () { - test('evaluates APGAR score formula - Normal case', () { - final formula = Formula( - name: "Apgar Score", - description: "Newborn health assessment scoring system", - input: [ - VariableSpec(name: "HeartRate", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "Breathing", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "MuscleTone", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "Reflexes", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "SkinColor", values: ["hr1", "hr2", "hr3"]) - ], - output: VariableSpec(name: "Result", unit: "stringscalar"), - d4rtCode: """ - var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor; - var interpretation = switch (total) { - >= 7 => 'Normal', - 4-6 => 'Requires attention', - _ => 'Emergency care needed' - }; - Result = 'Score: \$total - \$interpretation'; - """, - ); - - // Test normal case (score 7-10) - final result = evaluator.evaluate(formula, { - 'HeartRate': 2, - 'Breathing': 2, - 'MuscleTone': 2, - 'Reflexes': 2, - 'SkinColor': 2 - }); - - expect(result, 'Score: 10 - Normal'); - }); - - test('evaluates APGAR score formula - Requires attention case', () { - final formula = Formula( - name: "Apgar Score", - description: "Newborn health assessment scoring system", - input: [ - VariableSpec(name: "HeartRate", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "Breathing", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "MuscleTone", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "Reflexes", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "SkinColor", values: ["hr1", "hr2", "hr3"]) - ], - output: VariableSpec(name: "Result", unit: "stringscalar"), - d4rtCode: """ - var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor; - var interpretation = switch (total) { - >= 7 => 'Normal', - 4-6 => 'Requires attention', - _ => 'Emergency care needed' - }; - Result = 'Score: \$total - \$interpretation'; - """, - ); - - // Test requires attention case (score 4-6) - final result = evaluator.evaluate(formula, { - 'HeartRate': 1, - 'Breathing': 1, - 'MuscleTone': 1, - 'Reflexes': 1, - 'SkinColor': 2 - }); - - expect(result, 'Score: 6 - Requires attention'); - }); - - test('evaluates APGAR score formula - Emergency case', () { - final formula = Formula( - name: "Apgar Score", - description: "Newborn health assessment scoring system", - input: [ - VariableSpec(name: "HeartRate", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "Breathing", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "MuscleTone", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "Reflexes", values: ["hr1", "hr2", "hr3"]), - VariableSpec(name: "SkinColor", values: ["hr1", "hr2", "hr3"]) - ], - output: VariableSpec(name: "Result", unit: "stringscalar"), - d4rtCode: """ - var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor; - var interpretation = switch (total) { - >= 7 => 'Normal', - 4-6 => 'Requires attention', - _ => 'Emergency care needed' - }; - Result = 'Score: \$total - \$interpretation'; - """, - ); - - // Test emergency case (score 0-3) - final result = evaluator.evaluate(formula, { - 'HeartRate': 0, - 'Breathing': 0, - 'MuscleTone': 1, - 'Reflexes': 0, - 'SkinColor': 1 - }); - - expect(result, 'Score: 2 - Emergency care needed'); - }); - }); }); } diff --git a/test/formula_models_test.dart b/test/formula_models_test.dart index 3979a2b..1456b3a 100644 --- a/test/formula_models_test.dart +++ b/test/formula_models_test.dart @@ -1,16 +1,21 @@ import 'package:d4rt_formulas/corpus.dart'; import 'package:d4rt_formulas/defaults/default_corpus.dart'; import 'package:d4rt_formulas/formula_evaluator.dart'; -import 'package:test/test.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:d4rt_formulas/formula_models.dart'; void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + Future createTestCorpus() async { return createDefaultCorpus(); } + Future testCorpus = createTestCorpus(); + + test("Parses unit", () { final setLiteral = {"name": "kilometer", "symbol": "km", "baseUnit": "meter", "factor": 1000}; final unit = UnitSpec.fromSet(setLiteral); @@ -23,37 +28,37 @@ void main() { }); test("From km to in", () async { - final corpus = await createTestCorpus(); + final corpus = await testCorpus; final inches = corpus.convert(1, "kilometer", "inch"); expect( inches, closeTo(39370.078,0.001) ); }); test("From furlong to base", () async { - final corpus = await createTestCorpus(); + final corpus = await testCorpus; final m = corpus.convert(1, "furlong", "meter"); expect(m,closeTo(201.168,0.001)); }); test("From base to furlong", () async { - final corpus = await createTestCorpus(); + final corpus = await testCorpus; final m = corpus.convert(201.168, "meter", "furlong"); expect(m,closeTo(1,0.001)); }); test("From C to F", () async { - final corpus = await createTestCorpus(); + final corpus = await testCorpus; final m = corpus.convert(37, "Celsius", "Fahrenheit"); expect(m,closeTo(98.6,0.001)); }); test("From K to F", () async { - final corpus = await createTestCorpus(); + final corpus = await testCorpus; final m = corpus.convert(37, "Kelvin", "Fahrenheit"); expect(m,closeTo(-393.07,0.001)); }); test("From C to K", () async { - final corpus = await createTestCorpus(); + final corpus = await testCorpus; final m = corpus.convert(100, "Celsius", "Kelvin"); expect(m,closeTo(373.15,0.001)); }); @@ -108,5 +113,22 @@ void main() { expect(result, 98.0); // F = m * a = 10 * 9.8 = 98 N }); + group('APGAR Score', () { + test('evaluates APGAR score formula - Normal case', () async { + final corpus = await testCorpus; + final formula = corpus.getFormula("Apgar Score")!; + final evaluator = FormulaEvaluator(); + + final result = evaluator.evaluate(formula, { + 'HeartRate': 2, + 'Breathing': 2, + 'MuscleTone': 2, + 'Reflexes': 2, + 'SkinColor': 2 + }); + + expect(result, 'Score: 10 - Normal'); + }); + }); } From 3f97327451b9dcf3659b4d773dd2d2442e44ba64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Sun, 25 Jan 2026 19:06:09 +0100 Subject: [PATCH 9/9] faltaba .lock --- pubspec.lock | 706 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 706 insertions(+) create mode 100644 pubspec.lock diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..78823f5 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,706 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f + url: "https://pub.dev" + source: hosted + version: "85.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "974859dc0ff5f37bc4313244b3218c791810d03ab3470a579580279ba971a48d" + url: "https://pub.dev" + source: hosted + version: "7.7.1" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + async: + dependency: transitive + description: + name: async + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.dev" + source: hosted + version: "2.13.0" + autotrie: + dependency: transitive + description: + name: autotrie + sha256: "55da6faefb53cfcb0abb2f2ca8636123fb40e35286bb57440d2cf467568188f8" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + characters: + dependency: transitive + description: + name: characters + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + charcode: + dependency: transitive + description: + name: charcode + sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a + url: "https://pub.dev" + source: hosted + version: "1.4.0" + cli_config: + dependency: transitive + description: + name: cli_config + sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec + url: "https://pub.dev" + source: hosted + version: "0.2.0" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + collection: + dependency: "direct main" + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + coverage: + dependency: transitive + description: + name: coverage + sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d" + url: "https://pub.dev" + source: hosted + version: "1.15.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + d4rt: + dependency: "direct main" + description: + name: d4rt + sha256: eff6a10f31e9e5b60b99146a33204c5f2d74e20ac3eeb14132d8a8ed0921c6e1 + url: "https://pub.dev" + source: hosted + version: "0.1.9" + equatable: + dependency: transitive + description: + name: equatable + sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b" + url: "https://pub.dev" + source: hosted + version: "2.0.8" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_code_editor: + dependency: "direct main" + description: + name: flutter_code_editor + sha256: "9af48ba8e3558b6ea4bb98b84c5eb1649702acf53e61a84d88383eeb79b239b0" + url: "https://pub.dev" + source: hosted + version: "0.3.5" + flutter_d4rt: + dependency: "direct main" + description: + name: flutter_d4rt + sha256: "7ab9d3f91de5c10db115ccab1d9b1588946f744850f5bacc243cfc9041dd0a4c" + url: "https://pub.dev" + source: hosted + version: "0.0.5" + flutter_highlight: + dependency: transitive + description: + name: flutter_highlight + sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27" + url: "https://pub.dev" + source: hosted + version: "0.7.7+1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.dev" + source: hosted + version: "2.1.3" + highlight: + dependency: transitive + description: + name: highlight + sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + hive: + dependency: transitive + description: + name: hive + sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" + url: "https://pub.dev" + source: hosted + version: "2.2.3" + http: + dependency: transitive + description: + name: http + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.dev" + source: hosted + version: "3.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://pub.dev" + source: hosted + version: "1.0.5" + js: + dependency: transitive + description: + name: js + sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" + url: "https://pub.dev" + source: hosted + version: "0.7.2" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + linked_scroll_controller: + dependency: transitive + description: + name: linked_scroll_controller + sha256: e6020062bcf4ffc907ee7fd090fa971e65d8dfaac3c62baf601a3ced0b37986a + url: "https://pub.dev" + source: hosted + version: "0.2.0" + lints: + dependency: transitive + description: + name: lints + sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 + url: "https://pub.dev" + source: hosted + version: "6.0.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + markdown: + dependency: transitive + description: + name: markdown + sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1" + url: "https://pub.dev" + source: hosted + version: "7.3.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.dev" + source: hosted + version: "0.12.17" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" + source: hosted + version: "1.17.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + mocktail: + dependency: transitive + description: + name: mocktail + sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.dev" + source: hosted + version: "2.2.0" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pool: + dependency: transitive + description: + name: pool + sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" + url: "https://pub.dev" + source: hosted + version: "1.5.2" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + resource_portable: + dependency: "direct main" + description: + name: resource_portable + sha256: "8ffa33b0769645e26d82c8f4e79adde3dd34b9e0bba981166d4e3798f39cffd9" + url: "https://pub.dev" + source: hosted + version: "3.1.2" + scrollable_positioned_list: + dependency: transitive + description: + name: scrollable_positioned_list + sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287" + url: "https://pub.dev" + source: hosted + version: "0.3.8" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 + url: "https://pub.dev" + source: hosted + version: "1.1.3" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + url: "https://pub.dev" + source: hosted + version: "0.10.13" + source_span: + dependency: transitive + description: + name: source_span + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + url: "https://pub.dev" + source: hosted + version: "1.10.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test: + dependency: "direct dev" + description: + name: test + sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7" + url: "https://pub.dev" + source: hosted + version: "1.26.3" + test_api: + dependency: transitive + description: + name: test_api + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + url: "https://pub.dev" + source: hosted + version: "0.7.7" + test_core: + dependency: transitive + description: + name: test_core + sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0" + url: "https://pub.dev" + source: hosted + version: "0.6.12" + tuple: + dependency: transitive + description: + name: tuple + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 + url: "https://pub.dev" + source: hosted + version: "2.0.2" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + url_launcher: + dependency: transitive + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611" + url: "https://pub.dev" + source: hosted + version: "6.3.28" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad + url: "https://pub.dev" + source: hosted + version: "6.3.6" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + url: "https://pub.dev" + source: hosted + version: "3.2.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + url: "https://pub.dev" + source: hosted + version: "3.2.5" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f + url: "https://pub.dev" + source: hosted + version: "2.4.2" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + url: "https://pub.dev" + source: hosted + version: "3.1.5" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + url: "https://pub.dev" + source: hosted + version: "15.0.2" + watcher: + dependency: transitive + description: + name: watcher + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" +sdks: + dart: ">=3.10.7 <4.0.0" + flutter: ">=3.38.0"