ci: add keystore/key.properties to repo, fix NDK version, remove duplicate build.gradle
Build Release AAB / build (push) Failing after 6m58s
No files matched your search
@@ -35,21 +35,6 @@ jobs:
|
||||
- name: Run tests
|
||||
run: flutter test
|
||||
|
||||
- name: Decode keystore
|
||||
if: env.KEYSTORE_BASE64 != ''
|
||||
run: echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > siab-release.keystore
|
||||
env:
|
||||
KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
|
||||
|
||||
- name: Create key.properties
|
||||
run: |
|
||||
cat > android/key.properties <<EOF
|
||||
storePassword=Store_sc4l3
|
||||
keyPassword=Store_sc4l3
|
||||
keyAlias=siab
|
||||
storeFile=../siab-release.keystore
|
||||
EOF
|
||||
|
||||
- name: Build App Bundle
|
||||
run: |
|
||||
flutter build appbundle \
|
||||
@@ -58,8 +43,8 @@ jobs:
|
||||
--split-debug-info=build/debug-info \
|
||||
--dart-define=SIAB_DEVICE_NAME=SIAB
|
||||
env:
|
||||
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
KEYSTORE_PASSWORD: Store_sc4l3
|
||||
KEY_PASSWORD: Store_sc4l3
|
||||
|
||||
- name: Upload AAB artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
@@ -42,8 +42,3 @@ app.*.map.json
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
# Keystore and signing
|
||||
*.keystore
|
||||
*.jks
|
||||
android/key.properties
|
||||
@@ -1,45 +1,45 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "adc901062556672b4138e18a4dc62a4be8f4b3c2"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: android
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: ios
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: linux
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: macos
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: web
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: windows
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "adc901062556672b4138e18a4dc62a4be8f4b3c2"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: android
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: ios
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: linux
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: macos
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: web
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
- platform: windows
|
||||
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
@@ -1,93 +1,93 @@
|
||||
# Android Setup Guide
|
||||
|
||||
## Option 1: Use Physical Android Device (Recommended)
|
||||
|
||||
### Steps:
|
||||
|
||||
1. **Enable Developer Options on your Android device:**
|
||||
- Go to Settings > About Phone
|
||||
- Tap "Build Number" 7 times
|
||||
- Go back to Settings > Developer Options
|
||||
- Enable "USB Debugging"
|
||||
|
||||
2. **Connect device via USB:**
|
||||
```bash
|
||||
# Check if device is detected
|
||||
adb devices
|
||||
```
|
||||
|
||||
3. **Run the app:**
|
||||
```bash
|
||||
cd flutter_siab_app
|
||||
flutter run
|
||||
```
|
||||
|
||||
## Option 2: Use Android Emulator
|
||||
|
||||
### Install Android Studio:
|
||||
|
||||
1. Download Android Studio: https://developer.android.com/studio
|
||||
|
||||
2. Install Android SDK and create an emulator:
|
||||
- Open Android Studio
|
||||
- Tools > Device Manager
|
||||
- Create Virtual Device
|
||||
- Choose a device (e.g., Pixel 5)
|
||||
- Download a system image (API 30+ recommended)
|
||||
- Finish setup
|
||||
|
||||
3. **Start the emulator:**
|
||||
```bash
|
||||
# List available emulators
|
||||
flutter emulators
|
||||
|
||||
# Launch emulator (replace with your emulator name)
|
||||
flutter emulators --launch <emulator_id>
|
||||
```
|
||||
|
||||
4. **Run the app:**
|
||||
```bash
|
||||
cd flutter_siab_app
|
||||
flutter run
|
||||
```
|
||||
|
||||
## Option 3: Build APK and Install Manually
|
||||
|
||||
If you can't use USB debugging, build an APK:
|
||||
|
||||
```bash
|
||||
cd flutter_siab_app
|
||||
flutter build apk --release
|
||||
```
|
||||
|
||||
The APK will be at: `build/app/outputs/flutter-apk/app-release.apk`
|
||||
|
||||
Transfer to your Android device and install it.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No devices found"
|
||||
- Ensure USB debugging is enabled
|
||||
- Try different USB cable/port
|
||||
- Run `adb devices` to verify connection
|
||||
- On Linux, you may need to add udev rules
|
||||
|
||||
### "Permission denied"
|
||||
- Check USB debugging authorization on device
|
||||
- Try `adb kill-server && adb start-server`
|
||||
|
||||
### Bluetooth not working on emulator
|
||||
- Physical devices are recommended for Bluetooth testing
|
||||
- Some emulators don't support Bluetooth BLE
|
||||
- Use a real Android device for best results
|
||||
|
||||
## Required Permissions
|
||||
|
||||
The app needs these permissions (already configured):
|
||||
- Bluetooth
|
||||
- Bluetooth Admin
|
||||
- Bluetooth Scan
|
||||
- Bluetooth Connect
|
||||
- Location (required for BLE scanning on Android 12+)
|
||||
|
||||
Make sure to grant all permissions when the app requests them.
|
||||
# Android Setup Guide
|
||||
|
||||
## Option 1: Use Physical Android Device (Recommended)
|
||||
|
||||
### Steps:
|
||||
|
||||
1. **Enable Developer Options on your Android device:**
|
||||
- Go to Settings > About Phone
|
||||
- Tap "Build Number" 7 times
|
||||
- Go back to Settings > Developer Options
|
||||
- Enable "USB Debugging"
|
||||
|
||||
2. **Connect device via USB:**
|
||||
```bash
|
||||
# Check if device is detected
|
||||
adb devices
|
||||
```
|
||||
|
||||
3. **Run the app:**
|
||||
```bash
|
||||
cd flutter_siab_app
|
||||
flutter run
|
||||
```
|
||||
|
||||
## Option 2: Use Android Emulator
|
||||
|
||||
### Install Android Studio:
|
||||
|
||||
1. Download Android Studio: https://developer.android.com/studio
|
||||
|
||||
2. Install Android SDK and create an emulator:
|
||||
- Open Android Studio
|
||||
- Tools > Device Manager
|
||||
- Create Virtual Device
|
||||
- Choose a device (e.g., Pixel 5)
|
||||
- Download a system image (API 30+ recommended)
|
||||
- Finish setup
|
||||
|
||||
3. **Start the emulator:**
|
||||
```bash
|
||||
# List available emulators
|
||||
flutter emulators
|
||||
|
||||
# Launch emulator (replace with your emulator name)
|
||||
flutter emulators --launch <emulator_id>
|
||||
```
|
||||
|
||||
4. **Run the app:**
|
||||
```bash
|
||||
cd flutter_siab_app
|
||||
flutter run
|
||||
```
|
||||
|
||||
## Option 3: Build APK and Install Manually
|
||||
|
||||
If you can't use USB debugging, build an APK:
|
||||
|
||||
```bash
|
||||
cd flutter_siab_app
|
||||
flutter build apk --release
|
||||
```
|
||||
|
||||
The APK will be at: `build/app/outputs/flutter-apk/app-release.apk`
|
||||
|
||||
Transfer to your Android device and install it.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No devices found"
|
||||
- Ensure USB debugging is enabled
|
||||
- Try different USB cable/port
|
||||
- Run `adb devices` to verify connection
|
||||
- On Linux, you may need to add udev rules
|
||||
|
||||
### "Permission denied"
|
||||
- Check USB debugging authorization on device
|
||||
- Try `adb kill-server && adb start-server`
|
||||
|
||||
### Bluetooth not working on emulator
|
||||
- Physical devices are recommended for Bluetooth testing
|
||||
- Some emulators don't support Bluetooth BLE
|
||||
- Use a real Android device for best results
|
||||
|
||||
## Required Permissions
|
||||
|
||||
The app needs these permissions (already configured):
|
||||
- Bluetooth
|
||||
- Bluetooth Admin
|
||||
- Bluetooth Scan
|
||||
- Bluetooth Connect
|
||||
- Location (required for BLE scanning on Android 12+)
|
||||
|
||||
Make sure to grant all permissions when the app requests them.
|
||||
@@ -1,78 +1,78 @@
|
||||
# Quick Start Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Install Flutter: https://flutter.dev/docs/get-started/install
|
||||
2. Install Android Studio or VS Code with Flutter extensions
|
||||
3. Enable developer options on your Android device
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. **Navigate to the app directory:**
|
||||
```bash
|
||||
cd flutter_siab_app
|
||||
```
|
||||
|
||||
2. **Get Flutter dependencies:**
|
||||
```bash
|
||||
flutter pub get
|
||||
```
|
||||
|
||||
3. **Connect your Android device** (USB debugging enabled) or start an emulator
|
||||
|
||||
4. **Run the app:**
|
||||
```bash
|
||||
flutter run
|
||||
```
|
||||
|
||||
## First Run
|
||||
|
||||
1. **Grant Permissions:**
|
||||
- The app will request Bluetooth and Location permissions
|
||||
- Grant all permissions (Location is required for BLE scanning on Android)
|
||||
|
||||
2. **Connect to SIAB Device:**
|
||||
- Tap the blue floating action button (FAB) at bottom right
|
||||
- App will scan for devices named "SIAB"
|
||||
- Once found, it will connect automatically
|
||||
- If no data arrives, it will try common start commands
|
||||
|
||||
3. **View Data:**
|
||||
- Streamed data packets appear in real-time
|
||||
- Tap any packet to see detailed information
|
||||
- View statistics at the top
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ One-tap connect/disconnect
|
||||
- ✅ Real-time data streaming
|
||||
- ✅ Detailed packet information
|
||||
- ✅ Statistics (count, rate, duration)
|
||||
- ✅ Automatic start command detection
|
||||
- ✅ Clean, Material Design UI
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No devices found"
|
||||
- Ensure SIAB device is powered on
|
||||
- Check device name matches "SIAB" (case-insensitive)
|
||||
- Verify Bluetooth is enabled on both devices
|
||||
|
||||
### "Permission denied"
|
||||
- Go to Android Settings > Apps > SIAB Bluetooth > Permissions
|
||||
- Enable Location permission (required for BLE)
|
||||
|
||||
### "No data received"
|
||||
- App automatically tries start commands
|
||||
- Check device documentation for correct command
|
||||
- Device may need specific initialization sequence
|
||||
|
||||
## Building APK
|
||||
|
||||
To build a release APK:
|
||||
|
||||
```bash
|
||||
flutter build apk --release
|
||||
```
|
||||
|
||||
APK location: `build/app/outputs/flutter-apk/app-release.apk`
|
||||
# Quick Start Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Install Flutter: https://flutter.dev/docs/get-started/install
|
||||
2. Install Android Studio or VS Code with Flutter extensions
|
||||
3. Enable developer options on your Android device
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. **Navigate to the app directory:**
|
||||
```bash
|
||||
cd flutter_siab_app
|
||||
```
|
||||
|
||||
2. **Get Flutter dependencies:**
|
||||
```bash
|
||||
flutter pub get
|
||||
```
|
||||
|
||||
3. **Connect your Android device** (USB debugging enabled) or start an emulator
|
||||
|
||||
4. **Run the app:**
|
||||
```bash
|
||||
flutter run
|
||||
```
|
||||
|
||||
## First Run
|
||||
|
||||
1. **Grant Permissions:**
|
||||
- The app will request Bluetooth and Location permissions
|
||||
- Grant all permissions (Location is required for BLE scanning on Android)
|
||||
|
||||
2. **Connect to SIAB Device:**
|
||||
- Tap the blue floating action button (FAB) at bottom right
|
||||
- App will scan for devices named "SIAB"
|
||||
- Once found, it will connect automatically
|
||||
- If no data arrives, it will try common start commands
|
||||
|
||||
3. **View Data:**
|
||||
- Streamed data packets appear in real-time
|
||||
- Tap any packet to see detailed information
|
||||
- View statistics at the top
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ One-tap connect/disconnect
|
||||
- ✅ Real-time data streaming
|
||||
- ✅ Detailed packet information
|
||||
- ✅ Statistics (count, rate, duration)
|
||||
- ✅ Automatic start command detection
|
||||
- ✅ Clean, Material Design UI
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No devices found"
|
||||
- Ensure SIAB device is powered on
|
||||
- Check device name matches "SIAB" (case-insensitive)
|
||||
- Verify Bluetooth is enabled on both devices
|
||||
|
||||
### "Permission denied"
|
||||
- Go to Android Settings > Apps > SIAB Bluetooth > Permissions
|
||||
- Enable Location permission (required for BLE)
|
||||
|
||||
### "No data received"
|
||||
- App automatically tries start commands
|
||||
- Check device documentation for correct command
|
||||
- Device may need specific initialization sequence
|
||||
|
||||
## Building APK
|
||||
|
||||
To build a release APK:
|
||||
|
||||
```bash
|
||||
flutter build apk --release
|
||||
```
|
||||
|
||||
APK location: `build/app/outputs/flutter-apk/app-release.apk`
|
||||
@@ -1,28 +1,37 @@
|
||||
# This file configures the analyzer, which statically analyzes Dart code to
|
||||
# check for errors, warnings, and lints.
|
||||
#
|
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||
# invoked from the command line by running `flutter analyze`.
|
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps,
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
# included above or to enable additional rules. A list of all available lints
|
||||
# and their documentation is published at https://dart.dev/lints.
|
||||
#
|
||||
# Instead of disabling a lint rule for the entire project in the
|
||||
# section below, it can also be suppressed for a single line of code
|
||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
# This file configures the analyzer, which statically analyzes Dart code to
|
||||
# check for errors, warnings, and lints.
|
||||
#
|
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||
# invoked from the command line by running `flutter analyze`.
|
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps,
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
analyzer:
|
||||
exclude:
|
||||
- build/**
|
||||
- android/**
|
||||
- ios/**
|
||||
- web/**
|
||||
- windows/**
|
||||
- macos/**
|
||||
- linux/**
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
# included above or to enable additional rules. A list of all available lints
|
||||
# and their documentation is published at https://dart.dev/lints.
|
||||
#
|
||||
# Instead of disabling a lint rule for the entire project in the
|
||||
# section below, it can also be suppressed for a single line of code
|
||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
@@ -1,14 +1,14 @@
|
||||
gradle-wrapper.jar
|
||||
/.gradle
|
||||
/captures/
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
.cxx/
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/to/reference-keystore
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
gradle-wrapper.jar
|
||||
/.gradle
|
||||
/captures/
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
.cxx/
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/to/reference-keystore
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
@@ -1,80 +0,0 @@
|
||||
plugins {
|
||||
id "com.android.application"
|
||||
id "kotlin-android"
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
}
|
||||
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "id.ptsemangat.siab_scale"
|
||||
compileSdk 36
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "id.ptsemangat.siab_scale"
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
targetSdk 34
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file(keystoreProperties['storeFile'])
|
||||
storePassword keystoreProperties['storePassword']
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {}
|
||||
@@ -14,7 +14,7 @@ if (keystorePropertiesFile.exists()) {
|
||||
android {
|
||||
namespace = "id.ptsemangat.siab_scale"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = flutter.ndkVersion
|
||||
ndkVersion = "27.0.12077973"
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
-keep class io.flutter.** { *; }
|
||||
-keep class io.flutter.plugins.** { *; }
|
||||
|
||||
# Play Core deferred components
|
||||
-dontwarn com.google.android.play.core.**
|
||||
-dontwarn com.google.android.play.core.splitcompat.**
|
||||
-dontwarn com.google.android.play.core.splitinstall.**
|
||||
-dontwarn com.google.android.play.core.tasks.**
|
||||
|
||||
# SIAB Scale app
|
||||
-keep class id.ptsemangat.siab_scale.** { *; }
|
||||
|
||||
@@ -14,3 +20,4 @@
|
||||
|
||||
# sqflite
|
||||
-keep class com.tekartik.sqflite.** { *; }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
@@ -1,37 +1,37 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<!-- Storage permissions for saving CSV to Downloads on older Android versions -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>
|
||||
|
||||
<application
|
||||
android:label="SIAB Scale"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
</manifest>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<!-- Storage permissions for saving CSV to Downloads on older Android versions -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>
|
||||
|
||||
<application
|
||||
android:label="SIAB Scale"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
@@ -1,18 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -1,18 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -1,7 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
@@ -1,31 +0,0 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '2.0.0'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
@@ -1,24 +1,24 @@
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
val newBuildDir: Directory =
|
||||
rootProject.layout.buildDirectory
|
||||
.dir("../../build")
|
||||
.get()
|
||||
rootProject.layout.buildDirectory.value(newBuildDir)
|
||||
|
||||
subprojects {
|
||||
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
|
||||
project.layout.buildDirectory.value(newSubprojectBuildDir)
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(":app")
|
||||
}
|
||||
|
||||
tasks.register<Delete>("clean") {
|
||||
delete(rootProject.layout.buildDirectory)
|
||||
}
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
val newBuildDir: Directory =
|
||||
rootProject.layout.buildDirectory
|
||||
.dir("../../build")
|
||||
.get()
|
||||
rootProject.layout.buildDirectory.value(newBuildDir)
|
||||
|
||||
subprojects {
|
||||
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
|
||||
project.layout.buildDirectory.value(newSubprojectBuildDir)
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(":app")
|
||||
}
|
||||
|
||||
tasks.register<Delete>("clean") {
|
||||
delete(rootProject.layout.buildDirectory)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-all.zip
|
||||
@@ -1,26 +1,26 @@
|
||||
pluginManagement {
|
||||
val flutterSdkPath =
|
||||
run {
|
||||
val properties = java.util.Properties()
|
||||
file("local.properties").inputStream().use { properties.load(it) }
|
||||
val flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
|
||||
flutterSdkPath
|
||||
}
|
||||
|
||||
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||
id("com.android.application") version "8.9.1" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
|
||||
}
|
||||
|
||||
include(":app")
|
||||
pluginManagement {
|
||||
val flutterSdkPath =
|
||||
run {
|
||||
val properties = java.util.Properties()
|
||||
file("local.properties").inputStream().use { properties.load(it) }
|
||||
val flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
|
||||
flutterSdkPath
|
||||
}
|
||||
|
||||
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||
id("com.android.application") version "9.0.0" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
|
||||
}
|
||||
|
||||
include(":app")
|
||||
|
After Width: | Height: | Size: 174 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 432 432" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-11247.479417,-220.878492)">
|
||||
<g transform="matrix(3.556675,0,0,1,2063.451047,0)">
|
||||
<g transform="matrix(0.134003,0,0,0.476604,2271.742994,75.055391)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.959532,0,0,0.959532,-7272.887866,171.062992)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538ZM10624.96,701.428L10608.01,602.96C10599.711,554.748 10557.898,519.518 10508.977,519.518L10422.144,519.518C10372.585,519.518 10330.426,555.648 10322.839,604.623L10307.572,703.169C10302.871,733.512 10311.666,764.394 10331.647,787.709C10351.628,811.024 10380.799,824.442 10411.505,824.442L10521.312,824.442C10552.325,824.442 10581.758,810.754 10601.741,787.037C10621.724,763.32 10630.221,731.992 10624.96,701.428ZM10556.997,624.883L10571.236,707.601C10573.924,723.216 10569.583,739.222 10559.373,751.339C10549.163,763.456 10534.126,770.45 10518.281,770.45L10414.485,770.45C10398.797,770.45 10383.893,763.594 10373.685,751.682C10363.476,739.771 10358.983,723.993 10361.385,708.49L10374.179,625.907C10378.85,595.755 10404.806,573.511 10435.317,573.511L10496.026,573.511C10526.145,573.511 10551.887,595.201 10556.997,624.883ZM10518.185,644.084L10485.169,677.1C10481.077,681.192 10474.443,681.192 10470.352,677.1L10460.989,667.737C10456.897,663.646 10456.897,657.012 10460.989,652.92C10470.018,643.891 10485.161,628.748 10494.002,619.902C10495.699,618.205 10496.43,615.769 10495.948,613.418C10495.466,611.068 10493.836,609.116 10491.609,608.224C10483.596,604.979 10474.84,603.193 10465.67,603.193C10427.463,603.193 10396.444,634.212 10396.444,672.419C10396.444,710.626 10427.463,741.645 10465.67,741.645C10503.877,741.645 10534.896,710.626 10534.896,672.419C10534.896,663.249 10533.11,654.493 10529.869,646.479C10528.976,644.25 10527.024,642.619 10524.672,642.137C10522.319,641.655 10519.882,642.386 10518.185,644.084ZM10323.418,417.171L10326.515,437.161C10331.987,472.482 10362.392,498.54 10398.135,498.54L10532.582,498.54C10567.865,498.54 10598.02,473.132 10604.006,438.36L10607.56,417.711C10608.244,413.738 10607.143,409.665 10604.55,406.578C10601.958,403.491 10598.137,401.702 10594.105,401.689L10568.061,401.604C10561.653,401.583 10556.086,406.008 10554.661,412.256L10550.796,429.201C10549.269,438.068 10541.579,444.547 10532.582,444.547L10398.135,444.547C10389.02,444.547 10381.267,437.902 10379.871,428.895L10377.426,413.111C10376.396,406.46 10370.687,401.543 10363.957,401.51L10337.023,401.375C10333.012,401.355 10329.194,403.094 10326.576,406.134C10323.958,409.173 10322.804,413.207 10323.418,417.171Z" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 432 432" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-11876.484028,-220.878492)">
|
||||
<g transform="matrix(3.556675,0,0,1,2063.451047,0)">
|
||||
<g transform="matrix(0.134003,0,0,0.476604,2448.59488,75.055391)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.959532,0,0,0.959532,-7272.887866,171.062992)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538ZM10624.96,701.428L10608.01,602.96C10599.711,554.748 10557.898,519.518 10508.977,519.518L10422.144,519.518C10372.585,519.518 10330.426,555.648 10322.839,604.623L10307.572,703.169C10302.871,733.512 10311.666,764.394 10331.647,787.709C10351.628,811.024 10380.799,824.442 10411.505,824.442L10521.312,824.442C10552.325,824.442 10581.758,810.754 10601.741,787.037C10621.724,763.32 10630.221,731.992 10624.96,701.428ZM10556.997,624.883L10571.236,707.601C10573.924,723.216 10569.583,739.222 10559.373,751.339C10549.163,763.456 10534.126,770.45 10518.281,770.45L10414.485,770.45C10398.797,770.45 10383.893,763.594 10373.685,751.682C10363.476,739.771 10358.983,723.993 10361.385,708.49L10374.179,625.907C10378.85,595.755 10404.806,573.511 10435.317,573.511L10496.026,573.511C10526.145,573.511 10551.887,595.201 10556.997,624.883ZM10518.185,644.084L10485.169,677.1C10481.077,681.192 10474.443,681.192 10470.352,677.1L10460.989,667.737C10456.897,663.646 10456.897,657.012 10460.989,652.92C10470.018,643.891 10485.161,628.748 10494.002,619.902C10495.699,618.205 10496.43,615.769 10495.948,613.418C10495.466,611.068 10493.836,609.116 10491.609,608.224C10483.596,604.979 10474.84,603.193 10465.67,603.193C10427.463,603.193 10396.444,634.212 10396.444,672.419C10396.444,710.626 10427.463,741.645 10465.67,741.645C10503.877,741.645 10534.896,710.626 10534.896,672.419C10534.896,663.249 10533.11,654.493 10529.869,646.479C10528.976,644.25 10527.024,642.619 10524.672,642.137C10522.319,641.655 10519.882,642.386 10518.185,644.084ZM10323.418,417.171L10326.515,437.161C10331.987,472.482 10362.392,498.54 10398.135,498.54L10532.582,498.54C10567.865,498.54 10598.02,473.132 10604.006,438.36L10607.56,417.711C10608.244,413.738 10607.143,409.665 10604.55,406.578C10601.958,403.491 10598.137,401.702 10594.105,401.689L10568.061,401.604C10561.653,401.583 10556.086,406.008 10554.661,412.256L10550.796,429.201C10549.269,438.068 10541.579,444.547 10532.582,444.547L10398.135,444.547C10389.02,444.547 10381.267,437.902 10379.871,428.895L10377.426,413.111C10376.396,406.46 10370.687,401.543 10363.957,401.51L10337.023,401.375C10333.012,401.355 10329.194,403.094 10326.576,406.134C10323.958,409.173 10322.804,413.207 10323.418,417.171Z" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 432 432" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-10629.023523,-220.878492)">
|
||||
<g transform="matrix(3.556675,0,0,1,2063.451047,0)">
|
||||
<g transform="matrix(0.84375,0,0,0.84375,-299.008261,-854.902758)">
|
||||
<g transform="matrix(0.103708,0,0,0.368856,2971.190037,1118.626194)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.152391,0,0,0.542006,1685.662521,1198.800036)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538ZM10323.418,417.171L10326.515,437.161C10331.987,472.482 10362.392,498.54 10398.135,498.54L10532.582,498.54C10567.865,498.54 10598.02,473.132 10604.006,438.36L10607.56,417.711C10608.244,413.738 10607.143,409.665 10604.55,406.578C10601.958,403.491 10598.137,401.702 10594.105,401.689L10568.061,401.604C10561.653,401.583 10556.086,406.008 10554.661,412.256L10550.796,429.201C10549.269,438.068 10541.579,444.547 10532.582,444.547L10398.135,444.547C10389.02,444.547 10381.267,437.902 10379.871,428.895L10377.426,413.111C10376.396,406.46 10370.687,401.543 10363.957,401.51L10337.023,401.375C10333.012,401.355 10329.194,403.094 10326.576,406.134C10323.958,409.173 10322.804,413.207 10323.418,417.171ZM10624.96,701.428L10608.01,602.96C10599.711,554.748 10557.898,519.518 10508.977,519.518L10422.144,519.518C10372.585,519.518 10330.426,555.648 10322.839,604.623L10307.572,703.169C10302.871,733.512 10311.666,764.394 10331.647,787.709C10351.628,811.024 10380.799,824.442 10411.505,824.442L10521.312,824.442C10552.325,824.442 10581.758,810.754 10601.741,787.037C10621.724,763.32 10630.221,731.992 10624.96,701.428ZM10556.997,624.883L10571.236,707.601C10573.924,723.216 10569.583,739.222 10559.373,751.339C10549.163,763.456 10534.126,770.45 10518.281,770.45L10414.485,770.45C10398.797,770.45 10383.893,763.594 10373.685,751.682C10363.476,739.771 10358.983,723.993 10361.385,708.49L10374.179,625.907C10378.85,595.755 10404.806,573.511 10435.317,573.511L10496.026,573.511C10526.145,573.511 10551.887,595.201 10556.997,624.883ZM10518.185,644.084L10485.169,677.1C10481.077,681.192 10474.443,681.192 10470.352,677.1L10460.989,667.737C10456.897,663.646 10456.897,657.012 10460.989,652.92C10470.018,643.891 10485.161,628.748 10494.002,619.902C10495.699,618.205 10496.43,615.769 10495.948,613.418C10495.466,611.068 10493.836,609.116 10491.609,608.224C10483.596,604.979 10474.84,603.193 10465.67,603.193C10427.463,603.193 10396.444,634.212 10396.444,672.419C10396.444,710.626 10427.463,741.645 10465.67,741.645C10503.877,741.645 10534.896,710.626 10534.896,672.419C10534.896,663.249 10533.11,654.493 10529.869,646.479C10528.976,644.25 10527.024,642.619 10524.672,642.137C10522.319,641.655 10519.882,642.386 10518.185,644.084Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.281162,0,0,1,-580.163012,0)">
|
||||
<path d="M13654.154,1424.909C13653.821,1422.761 13654.447,1420.574 13655.866,1418.927C13657.284,1417.279 13659.354,1416.337 13661.528,1416.348L13676.126,1416.42C13679.774,1416.439 13682.868,1419.104 13683.427,1422.708L13684.752,1431.264C13685.508,1436.146 13689.711,1439.747 13694.651,1439.747L13767.522,1439.747C13772.399,1439.747 13776.567,1436.235 13777.394,1431.429L13779.489,1422.245C13780.261,1418.858 13783.278,1416.46 13786.752,1416.471L13800.868,1416.518C13803.053,1416.525 13805.124,1417.494 13806.529,1419.168C13807.935,1420.841 13808.531,1423.048 13808.161,1425.202L13806.234,1436.394C13802.99,1455.24 13786.645,1469.012 13767.522,1469.012L13694.651,1469.012C13675.278,1469.012 13658.798,1454.888 13655.832,1435.744L13654.154,1424.909Z" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.281162,0,0,1,-580.163012,0)">
|
||||
<path d="M13817.591,1578.978C13820.443,1595.544 13815.838,1612.524 13805.007,1625.379C13794.176,1638.233 13778.223,1645.652 13761.414,1645.652L13701.897,1645.652C13685.255,1645.652 13669.444,1638.379 13658.614,1625.743C13647.784,1613.106 13643.018,1596.368 13645.565,1579.921L13653.84,1526.509C13657.953,1499.965 13680.803,1480.382 13707.664,1480.382L13754.728,1480.382C13781.244,1480.382 13803.906,1499.477 13808.405,1525.608L13817.591,1578.978ZM13780.755,1537.49C13777.986,1521.402 13764.033,1509.646 13747.708,1509.646L13714.804,1509.646C13698.267,1509.646 13684.198,1521.703 13681.667,1538.045L13674.732,1582.806C13673.43,1591.208 13675.866,1599.76 13681.399,1606.216C13686.932,1612.672 13695.01,1616.388 13703.513,1616.388L13759.771,1616.388C13768.359,1616.388 13776.509,1612.598 13782.043,1606.03C13787.576,1599.462 13789.929,1590.787 13788.472,1582.324L13780.755,1537.49Z" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.281162,0,0,1,-580.163012,0)">
|
||||
<path d="M13759.719,1547.897C13760.639,1546.977 13761.96,1546.58 13763.234,1546.842C13764.509,1547.103 13765.568,1547.987 13766.052,1549.195C13767.808,1553.539 13768.776,1558.285 13768.776,1563.255C13768.776,1583.963 13751.964,1600.776 13731.255,1600.776C13710.547,1600.776 13693.735,1583.963 13693.735,1563.255C13693.735,1542.546 13710.547,1525.734 13731.255,1525.734C13736.226,1525.734 13740.971,1526.702 13745.314,1528.461C13746.521,1528.944 13747.405,1530.002 13747.666,1531.276C13747.927,1532.55 13747.531,1533.871 13746.611,1534.79C13741.819,1539.585 13733.612,1547.793 13728.718,1552.686C13726.5,1554.904 13726.501,1558.5 13728.718,1560.717L13733.793,1565.792C13736.01,1568.01 13739.606,1568.01 13741.824,1565.792L13759.719,1547.897Z" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.2 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 432 432" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-10052.182314,-215.925716)">
|
||||
<g transform="matrix(3.556675,0,0,1,2063.451047,0)">
|
||||
<g transform="matrix(0.134003,0,0,0.476604,1935.671456,70.102616)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.646902,0,0,0.646902,822.275361,112.266714)">
|
||||
<g transform="matrix(1.483273,0,0,1.483273,-12513.742858,90.889027)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.837848,0,0,0.837848,563.311523,258.627883)">
|
||||
<g transform="matrix(0.764685,0,0,0.764685,1814.51336,-94.801291)">
|
||||
<g transform="matrix(0.843817,0,0,1,973.42738,670.673266)">
|
||||
<path d="M996.456,815.382C1010.891,886.141 987.579,958.668 932.752,1013.576C877.925,1068.484 797.174,1100.174 712.085,1100.174C614.422,1100.174 508.13,1100.174 410.814,1100.174C326.571,1100.174 246.534,1069.108 191.713,1015.131C136.893,961.155 112.765,889.659 125.662,819.41C139.686,743.025 154.576,661.927 167.549,591.266C188.366,477.884 304.034,394.237 440.005,394.237C516.746,394.237 601.794,394.237 678.242,394.237C812.464,394.237 927.183,475.799 949.952,587.417C964.298,657.739 980.831,738.787 996.456,815.382ZM809.991,638.17C795.972,569.452 725.344,519.237 642.709,519.237C589.643,519.237 529.429,519.237 476.147,519.237C392.435,519.237 321.222,570.735 308.406,640.54C297.616,699.31 284.584,770.291 273.304,831.73C266.715,867.62 279.042,904.148 307.05,931.725C335.058,959.302 375.949,975.174 418.99,975.174C507.403,975.174 614.937,975.174 703.769,975.174C747.242,975.174 788.498,958.983 816.51,930.93C844.521,902.878 856.431,865.823 849.056,829.672C836.451,767.879 821.939,696.744 809.991,638.17Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.843817,0,0,-1,973.42738,1410.581134)">
|
||||
<path d="M169.137,582.616C167.452,591.793 170.619,601.132 177.801,608.169C184.983,615.205 195.46,619.231 206.465,619.185C230.149,619.085 258.821,618.965 280.361,618.874C298.825,618.797 314.488,607.413 317.315,592.016C320.486,574.745 324.024,555.473 324.024,555.473C327.852,534.621 349.125,519.237 374.132,519.237L743.005,519.237C767.69,519.237 788.789,534.237 792.976,554.765C792.976,554.765 798.715,575.995 803.581,593.996C807.492,608.461 822.764,618.705 840.347,618.656C860.96,618.6 888.653,618.523 911.802,618.459C922.863,618.429 933.347,614.288 940.46,607.14C947.573,599.993 950.594,590.564 948.718,581.365C944.059,558.529 938.966,533.56 938.966,533.56C922.544,453.06 839.808,394.237 743.005,394.237L374.132,394.237C276.068,394.237 192.647,454.564 177.634,536.336C177.634,536.336 173.216,560.398 169.137,582.616Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.923041,-0,0,0.923041,854.504081,621.345248)">
|
||||
<path d="M771.961,792.978C776.219,788.719 782.332,786.884 788.231,788.093C794.131,789.302 799.029,793.394 801.268,798.984C809.395,819.084 813.877,841.045 813.877,864.045C813.877,959.873 736.076,1037.674 640.248,1037.674C544.419,1037.674 466.619,959.873 466.619,864.045C466.619,768.216 544.419,690.416 640.248,690.416C663.247,690.416 685.208,694.897 705.305,703.034C710.892,705.272 714.981,710.167 716.189,716.063C717.398,721.96 715.564,728.068 711.308,732.324C689.133,754.513 651.152,792.493 628.507,815.139C618.244,825.402 618.244,842.041 628.507,852.303C635.961,859.758 644.535,868.331 651.989,875.786C662.252,886.048 678.891,886.048 689.153,875.786C711.799,853.14 749.779,815.16 771.961,792.978Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 432 432" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-13047.92582,-215.925716)">
|
||||
<g transform="matrix(3.556675,0,0,1,2063.451047,0)">
|
||||
<g transform="matrix(0.134003,0,0,0.476604,2777.959223,70.102616)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.646902,0,0,0.646902,822.275361,112.266714)">
|
||||
<g transform="matrix(1.483273,0,0,1.483273,-12513.742858,90.889027)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.837848,0,0,0.837848,563.311523,258.627883)">
|
||||
<g transform="matrix(0.764685,0,0,0.764685,1814.51336,-94.801291)">
|
||||
<g transform="matrix(0.843817,0,0,1,973.42738,670.673266)">
|
||||
<path d="M996.456,815.382C1010.891,886.141 987.579,958.668 932.752,1013.576C877.925,1068.484 797.174,1100.174 712.085,1100.174C614.422,1100.174 508.13,1100.174 410.814,1100.174C326.571,1100.174 246.534,1069.108 191.713,1015.131C136.893,961.155 112.765,889.659 125.662,819.41C139.686,743.025 154.576,661.927 167.549,591.266C188.366,477.884 304.034,394.237 440.005,394.237C516.746,394.237 601.794,394.237 678.242,394.237C812.464,394.237 927.183,475.799 949.952,587.417C964.298,657.739 980.831,738.787 996.456,815.382ZM809.991,638.17C795.972,569.452 725.344,519.237 642.709,519.237C589.643,519.237 529.429,519.237 476.147,519.237C392.435,519.237 321.222,570.735 308.406,640.54C297.616,699.31 284.584,770.291 273.304,831.73C266.715,867.62 279.042,904.148 307.05,931.725C335.058,959.302 375.949,975.174 418.99,975.174C507.403,975.174 614.937,975.174 703.769,975.174C747.242,975.174 788.498,958.983 816.51,930.93C844.521,902.878 856.431,865.823 849.056,829.672C836.451,767.879 821.939,696.744 809.991,638.17Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.843817,0,0,-1,973.42738,1410.581134)">
|
||||
<path d="M169.137,582.616C167.452,591.793 170.619,601.132 177.801,608.169C184.983,615.205 195.46,619.231 206.465,619.185C230.149,619.085 258.821,618.965 280.361,618.874C298.825,618.797 314.488,607.413 317.315,592.016C320.486,574.745 324.024,555.473 324.024,555.473C327.852,534.621 349.125,519.237 374.132,519.237L743.005,519.237C767.69,519.237 788.789,534.237 792.976,554.765C792.976,554.765 798.715,575.995 803.581,593.996C807.492,608.461 822.764,618.705 840.347,618.656C860.96,618.6 888.653,618.523 911.802,618.459C922.863,618.429 933.347,614.288 940.46,607.14C947.573,599.993 950.594,590.564 948.718,581.365C944.059,558.529 938.966,533.56 938.966,533.56C922.544,453.06 839.808,394.237 743.005,394.237L374.132,394.237C276.068,394.237 192.647,454.564 177.634,536.336C177.634,536.336 173.216,560.398 169.137,582.616Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.923041,-0,0,0.923041,854.504081,621.345248)">
|
||||
<path d="M771.961,792.978C776.219,788.719 782.332,786.884 788.231,788.093C794.131,789.302 799.029,793.394 801.268,798.984C809.395,819.084 813.877,841.045 813.877,864.045C813.877,959.873 736.076,1037.674 640.248,1037.674C544.419,1037.674 466.619,959.873 466.619,864.045C466.619,768.216 544.419,690.416 640.248,690.416C663.247,690.416 685.208,694.897 705.305,703.034C710.892,705.272 714.981,710.167 716.189,716.063C717.398,721.96 715.564,728.068 711.308,732.324C689.133,754.513 651.152,792.493 628.507,815.139C618.244,825.402 618.244,842.041 628.507,852.303C635.961,859.758 644.535,868.331 651.989,875.786C662.252,886.048 678.891,886.048 689.153,875.786C711.799,853.14 749.779,815.16 771.961,792.978Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 432 432" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-12479.308577,-215.925716)">
|
||||
<g transform="matrix(3.556675,0,0,1,2063.451047,0)">
|
||||
<g transform="matrix(0.134003,0,0,0.476604,2618.08594,70.102616)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.646902,0,0,0.646902,822.275361,112.266714)">
|
||||
<g transform="matrix(1.483273,0,0,1.483273,-12513.742858,90.889027)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.837848,0,0,0.837848,563.311523,258.627883)">
|
||||
<g transform="matrix(0.764685,0,0,0.764685,1814.51336,-94.801291)">
|
||||
<g transform="matrix(0.843817,0,0,1,973.42738,670.673266)">
|
||||
<path d="M996.456,815.382C1010.891,886.141 987.579,958.668 932.752,1013.576C877.925,1068.484 797.174,1100.174 712.085,1100.174C614.422,1100.174 508.13,1100.174 410.814,1100.174C326.571,1100.174 246.534,1069.108 191.713,1015.131C136.893,961.155 112.765,889.659 125.662,819.41C139.686,743.025 154.576,661.927 167.549,591.266C188.366,477.884 304.034,394.237 440.005,394.237C516.746,394.237 601.794,394.237 678.242,394.237C812.464,394.237 927.183,475.799 949.952,587.417C964.298,657.739 980.831,738.787 996.456,815.382ZM809.991,638.17C795.972,569.452 725.344,519.237 642.709,519.237C589.643,519.237 529.429,519.237 476.147,519.237C392.435,519.237 321.222,570.735 308.406,640.54C297.616,699.31 284.584,770.291 273.304,831.73C266.715,867.62 279.042,904.148 307.05,931.725C335.058,959.302 375.949,975.174 418.99,975.174C507.403,975.174 614.937,975.174 703.769,975.174C747.242,975.174 788.498,958.983 816.51,930.93C844.521,902.878 856.431,865.823 849.056,829.672C836.451,767.879 821.939,696.744 809.991,638.17Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.843817,0,0,-1,973.42738,1410.581134)">
|
||||
<path d="M169.137,582.616C167.452,591.793 170.619,601.132 177.801,608.169C184.983,615.205 195.46,619.231 206.465,619.185C230.149,619.085 258.821,618.965 280.361,618.874C298.825,618.797 314.488,607.413 317.315,592.016C320.486,574.745 324.024,555.473 324.024,555.473C327.852,534.621 349.125,519.237 374.132,519.237L743.005,519.237C767.69,519.237 788.789,534.237 792.976,554.765C792.976,554.765 798.715,575.995 803.581,593.996C807.492,608.461 822.764,618.705 840.347,618.656C860.96,618.6 888.653,618.523 911.802,618.459C922.863,618.429 933.347,614.288 940.46,607.14C947.573,599.993 950.594,590.564 948.718,581.365C944.059,558.529 938.966,533.56 938.966,533.56C922.544,453.06 839.808,394.237 743.005,394.237L374.132,394.237C276.068,394.237 192.647,454.564 177.634,536.336C177.634,536.336 173.216,560.398 169.137,582.616Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.923041,-0,0,0.923041,854.504081,621.345248)">
|
||||
<path d="M771.961,792.978C776.219,788.719 782.332,786.884 788.231,788.093C794.131,789.302 799.029,793.394 801.268,798.984C809.395,819.084 813.877,841.045 813.877,864.045C813.877,959.873 736.076,1037.674 640.248,1037.674C544.419,1037.674 466.619,959.873 466.619,864.045C466.619,768.216 544.419,690.416 640.248,690.416C663.247,690.416 685.208,694.897 705.305,703.034C710.892,705.272 714.981,710.167 716.189,716.063C717.398,721.96 715.564,728.068 711.308,732.324C689.133,754.513 651.152,792.493 628.507,815.139C618.244,825.402 618.244,842.041 628.507,852.303C635.961,859.758 644.535,868.331 651.989,875.786C662.252,886.048 678.891,886.048 689.153,875.786C711.799,853.14 749.779,815.16 771.961,792.978Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-11169.931337,726.774609)">
|
||||
<g transform="matrix(0.564865,0,0,0.564865,9861.276207,-899.601987)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.646902,0,0,0.646902,822.275361,112.266714)">
|
||||
<g transform="matrix(1.483273,0,0,1.483273,-12513.742858,90.889027)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.837848,0,0,0.837848,563.311523,258.627883)">
|
||||
<g transform="matrix(0.764685,0,0,0.764685,1814.51336,-94.801291)">
|
||||
<g transform="matrix(0.843817,0,0,1,973.42738,670.673266)">
|
||||
<path d="M996.456,815.382C1010.891,886.141 987.579,958.668 932.752,1013.576C877.925,1068.484 797.174,1100.174 712.085,1100.174C614.422,1100.174 508.13,1100.174 410.814,1100.174C326.571,1100.174 246.534,1069.108 191.713,1015.131C136.893,961.155 112.765,889.659 125.662,819.41C139.686,743.025 154.576,661.927 167.549,591.266C188.366,477.884 304.034,394.237 440.005,394.237C516.746,394.237 601.794,394.237 678.242,394.237C812.464,394.237 927.183,475.799 949.952,587.417C964.298,657.739 980.831,738.787 996.456,815.382ZM809.991,638.17C795.972,569.452 725.344,519.237 642.709,519.237C589.643,519.237 529.429,519.237 476.147,519.237C392.435,519.237 321.222,570.735 308.406,640.54C297.616,699.31 284.584,770.291 273.304,831.73C266.715,867.62 279.042,904.148 307.05,931.725C335.058,959.302 375.949,975.174 418.99,975.174C507.403,975.174 614.937,975.174 703.769,975.174C747.242,975.174 788.498,958.983 816.51,930.93C844.521,902.878 856.431,865.823 849.056,829.672C836.451,767.879 821.939,696.744 809.991,638.17Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.843817,0,0,-1,973.42738,1410.581134)">
|
||||
<path d="M169.137,582.616C167.452,591.793 170.619,601.132 177.801,608.169C184.983,615.205 195.46,619.231 206.465,619.185C230.149,619.085 258.821,618.965 280.361,618.874C298.825,618.797 314.488,607.413 317.315,592.016C320.486,574.745 324.024,555.473 324.024,555.473C327.852,534.621 349.125,519.237 374.132,519.237L743.005,519.237C767.69,519.237 788.789,534.237 792.976,554.765C792.976,554.765 798.715,575.995 803.581,593.996C807.492,608.461 822.764,618.705 840.347,618.656C860.96,618.6 888.653,618.523 911.802,618.459C922.863,618.429 933.347,614.288 940.46,607.14C947.573,599.993 950.594,590.564 948.718,581.365C944.059,558.529 938.966,533.56 938.966,533.56C922.544,453.06 839.808,394.237 743.005,394.237L374.132,394.237C276.068,394.237 192.647,454.564 177.634,536.336C177.634,536.336 173.216,560.398 169.137,582.616Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.923041,-0,0,0.923041,854.504081,621.345248)">
|
||||
<path d="M771.961,792.978C776.219,788.719 782.332,786.884 788.231,788.093C794.131,789.302 799.029,793.394 801.268,798.984C809.395,819.084 813.877,841.045 813.877,864.045C813.877,959.873 736.076,1037.674 640.248,1037.674C544.419,1037.674 466.619,959.873 466.619,864.045C466.619,768.216 544.419,690.416 640.248,690.416C663.247,690.416 685.208,694.897 705.305,703.034C710.892,705.272 714.981,710.167 716.189,716.063C717.398,721.96 715.564,728.068 711.308,732.324C689.133,754.513 651.152,792.493 628.507,815.139C618.244,825.402 618.244,842.041 628.507,852.303C635.961,859.758 644.535,868.331 651.989,875.786C662.252,886.048 678.891,886.048 689.153,875.786C711.799,853.14 749.779,815.16 771.961,792.978Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-9924.644661,726.774609)">
|
||||
<g transform="matrix(0.564865,0,0,0.564865,8615.989531,-899.601987)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.646902,0,0,0.646902,822.275361,112.266714)">
|
||||
<g transform="matrix(1.483273,0,0,1.483273,-12513.742858,90.889027)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.837848,0,0,0.837848,563.311523,258.627883)">
|
||||
<g transform="matrix(0.764685,0,0,0.764685,1814.51336,-94.801291)">
|
||||
<g transform="matrix(0.843817,0,0,1,973.42738,670.673266)">
|
||||
<path d="M996.456,815.382C1010.891,886.141 987.579,958.668 932.752,1013.576C877.925,1068.484 797.174,1100.174 712.085,1100.174C614.422,1100.174 508.13,1100.174 410.814,1100.174C326.571,1100.174 246.534,1069.108 191.713,1015.131C136.893,961.155 112.765,889.659 125.662,819.41C139.686,743.025 154.576,661.927 167.549,591.266C188.366,477.884 304.034,394.237 440.005,394.237C516.746,394.237 601.794,394.237 678.242,394.237C812.464,394.237 927.183,475.799 949.952,587.417C964.298,657.739 980.831,738.787 996.456,815.382ZM809.991,638.17C795.972,569.452 725.344,519.237 642.709,519.237C589.643,519.237 529.429,519.237 476.147,519.237C392.435,519.237 321.222,570.735 308.406,640.54C297.616,699.31 284.584,770.291 273.304,831.73C266.715,867.62 279.042,904.148 307.05,931.725C335.058,959.302 375.949,975.174 418.99,975.174C507.403,975.174 614.937,975.174 703.769,975.174C747.242,975.174 788.498,958.983 816.51,930.93C844.521,902.878 856.431,865.823 849.056,829.672C836.451,767.879 821.939,696.744 809.991,638.17Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.843817,0,0,-1,973.42738,1410.581134)">
|
||||
<path d="M169.137,582.616C167.452,591.793 170.619,601.132 177.801,608.169C184.983,615.205 195.46,619.231 206.465,619.185C230.149,619.085 258.821,618.965 280.361,618.874C298.825,618.797 314.488,607.413 317.315,592.016C320.486,574.745 324.024,555.473 324.024,555.473C327.852,534.621 349.125,519.237 374.132,519.237L743.005,519.237C767.69,519.237 788.789,534.237 792.976,554.765C792.976,554.765 798.715,575.995 803.581,593.996C807.492,608.461 822.764,618.705 840.347,618.656C860.96,618.6 888.653,618.523 911.802,618.459C922.863,618.429 933.347,614.288 940.46,607.14C947.573,599.993 950.594,590.564 948.718,581.365C944.059,558.529 938.966,533.56 938.966,533.56C922.544,453.06 839.808,394.237 743.005,394.237L374.132,394.237C276.068,394.237 192.647,454.564 177.634,536.336C177.634,536.336 173.216,560.398 169.137,582.616Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.923041,-0,0,0.923041,854.504081,621.345248)">
|
||||
<path d="M771.961,792.978C776.219,788.719 782.332,786.884 788.231,788.093C794.131,789.302 799.029,793.394 801.268,798.984C809.395,819.084 813.877,841.045 813.877,864.045C813.877,959.873 736.076,1037.674 640.248,1037.674C544.419,1037.674 466.619,959.873 466.619,864.045C466.619,768.216 544.419,690.416 640.248,690.416C663.247,690.416 685.208,694.897 705.305,703.034C710.892,705.272 714.981,710.167 716.189,716.063C717.398,721.96 715.564,728.068 711.308,732.324C689.133,754.513 651.152,792.493 628.507,815.139C618.244,825.402 618.244,842.041 628.507,852.303C635.961,859.758 644.535,868.331 651.989,875.786C662.252,886.048 678.891,886.048 689.153,875.786C711.799,853.14 749.779,815.16 771.961,792.978Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-10529.681152,726.774609)">
|
||||
<g transform="matrix(0.564865,0,0,0.564865,9221.026021,-899.601987)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.646902,0,0,0.646902,822.275361,112.266714)">
|
||||
<g transform="matrix(1.483273,0,0,1.483273,-12513.742858,90.889027)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.837848,0,0,0.837848,563.311523,258.627883)">
|
||||
<g transform="matrix(0.764685,0,0,0.764685,1814.51336,-94.801291)">
|
||||
<g transform="matrix(0.843817,0,0,1,973.42738,670.673266)">
|
||||
<path d="M996.456,815.382C1010.891,886.141 987.579,958.668 932.752,1013.576C877.925,1068.484 797.174,1100.174 712.085,1100.174C614.422,1100.174 508.13,1100.174 410.814,1100.174C326.571,1100.174 246.534,1069.108 191.713,1015.131C136.893,961.155 112.765,889.659 125.662,819.41C139.686,743.025 154.576,661.927 167.549,591.266C188.366,477.884 304.034,394.237 440.005,394.237C516.746,394.237 601.794,394.237 678.242,394.237C812.464,394.237 927.183,475.799 949.952,587.417C964.298,657.739 980.831,738.787 996.456,815.382ZM809.991,638.17C795.972,569.452 725.344,519.237 642.709,519.237C589.643,519.237 529.429,519.237 476.147,519.237C392.435,519.237 321.222,570.735 308.406,640.54C297.616,699.31 284.584,770.291 273.304,831.73C266.715,867.62 279.042,904.148 307.05,931.725C335.058,959.302 375.949,975.174 418.99,975.174C507.403,975.174 614.937,975.174 703.769,975.174C747.242,975.174 788.498,958.983 816.51,930.93C844.521,902.878 856.431,865.823 849.056,829.672C836.451,767.879 821.939,696.744 809.991,638.17Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.843817,0,0,-1,973.42738,1410.581134)">
|
||||
<path d="M169.137,582.616C167.452,591.793 170.619,601.132 177.801,608.169C184.983,615.205 195.46,619.231 206.465,619.185C230.149,619.085 258.821,618.965 280.361,618.874C298.825,618.797 314.488,607.413 317.315,592.016C320.486,574.745 324.024,555.473 324.024,555.473C327.852,534.621 349.125,519.237 374.132,519.237L743.005,519.237C767.69,519.237 788.789,534.237 792.976,554.765C792.976,554.765 798.715,575.995 803.581,593.996C807.492,608.461 822.764,618.705 840.347,618.656C860.96,618.6 888.653,618.523 911.802,618.459C922.863,618.429 933.347,614.288 940.46,607.14C947.573,599.993 950.594,590.564 948.718,581.365C944.059,558.529 938.966,533.56 938.966,533.56C922.544,453.06 839.808,394.237 743.005,394.237L374.132,394.237C276.068,394.237 192.647,454.564 177.634,536.336C177.634,536.336 173.216,560.398 169.137,582.616Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.923041,-0,0,0.923041,854.504081,621.345248)">
|
||||
<path d="M771.961,792.978C776.219,788.719 782.332,786.884 788.231,788.093C794.131,789.302 799.029,793.394 801.268,798.984C809.395,819.084 813.877,841.045 813.877,864.045C813.877,959.873 736.076,1037.674 640.248,1037.674C544.419,1037.674 466.619,959.873 466.619,864.045C466.619,768.216 544.419,690.416 640.248,690.416C663.247,690.416 685.208,694.897 705.305,703.034C710.892,705.272 714.981,710.167 716.189,716.063C717.398,721.96 715.564,728.068 711.308,732.324C689.133,754.513 651.152,792.493 628.507,815.139C618.244,825.402 618.244,842.041 628.507,852.303C635.961,859.758 644.535,868.331 651.989,875.786C662.252,886.048 678.891,886.048 689.153,875.786C711.799,853.14 749.779,815.16 771.961,792.978Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-16148.147117,726.774609)">
|
||||
<g transform="matrix(0.564865,0,0,0.564865,14839.491987,-899.601987)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.959532,0,0,0.959532,-7272.887866,171.062992)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538ZM10624.96,701.428L10608.01,602.96C10599.711,554.748 10557.898,519.518 10508.977,519.518L10422.144,519.518C10372.585,519.518 10330.426,555.648 10322.839,604.623L10307.572,703.169C10302.871,733.512 10311.666,764.394 10331.647,787.709C10351.628,811.024 10380.799,824.442 10411.505,824.442L10521.312,824.442C10552.325,824.442 10581.758,810.754 10601.741,787.037C10621.724,763.32 10630.221,731.992 10624.96,701.428ZM10556.997,624.883L10571.236,707.601C10573.924,723.216 10569.583,739.222 10559.373,751.339C10549.163,763.456 10534.126,770.45 10518.281,770.45L10414.485,770.45C10398.797,770.45 10383.893,763.594 10373.685,751.682C10363.476,739.771 10358.983,723.993 10361.385,708.49L10374.179,625.907C10378.85,595.755 10404.806,573.511 10435.317,573.511L10496.026,573.511C10526.145,573.511 10551.887,595.201 10556.997,624.883ZM10518.185,644.084L10485.169,677.1C10481.077,681.192 10474.443,681.192 10470.352,677.1L10460.989,667.737C10456.897,663.646 10456.897,657.012 10460.989,652.92C10470.018,643.891 10485.161,628.748 10494.002,619.902C10495.699,618.205 10496.43,615.769 10495.948,613.418C10495.466,611.068 10493.836,609.116 10491.609,608.224C10483.596,604.979 10474.84,603.193 10465.67,603.193C10427.463,603.193 10396.444,634.212 10396.444,672.419C10396.444,710.626 10427.463,741.645 10465.67,741.645C10503.877,741.645 10534.896,710.626 10534.896,672.419C10534.896,663.249 10533.11,654.493 10529.869,646.479C10528.976,644.25 10527.024,642.619 10524.672,642.137C10522.319,641.655 10519.882,642.386 10518.185,644.084ZM10323.418,417.171L10326.515,437.161C10331.987,472.482 10362.392,498.54 10398.135,498.54L10532.582,498.54C10567.865,498.54 10598.02,473.132 10604.006,438.36L10607.56,417.711C10608.244,413.738 10607.143,409.665 10604.55,406.578C10601.958,403.491 10598.137,401.702 10594.105,401.689L10568.061,401.604C10561.653,401.583 10556.086,406.008 10554.661,412.256L10550.796,429.201C10549.269,438.068 10541.579,444.547 10532.582,444.547L10398.135,444.547C10389.02,444.547 10381.267,437.902 10379.871,428.895L10377.426,413.111C10376.396,406.46 10370.687,401.543 10363.957,401.51L10337.023,401.375C10333.012,401.355 10329.194,403.094 10326.576,406.134C10323.958,409.173 10322.804,413.207 10323.418,417.171Z" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-14943.31376,726.774609)">
|
||||
<g transform="matrix(0.564865,0,0,0.564865,13634.65863,-899.601987)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.959532,0,0,0.959532,-7272.887866,171.062992)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538ZM10624.96,701.428L10608.01,602.96C10599.711,554.748 10557.898,519.518 10508.977,519.518L10422.144,519.518C10372.585,519.518 10330.426,555.648 10322.839,604.623L10307.572,703.169C10302.871,733.512 10311.666,764.394 10331.647,787.709C10351.628,811.024 10380.799,824.442 10411.505,824.442L10521.312,824.442C10552.325,824.442 10581.758,810.754 10601.741,787.037C10621.724,763.32 10630.221,731.992 10624.96,701.428ZM10556.997,624.883L10571.236,707.601C10573.924,723.216 10569.583,739.222 10559.373,751.339C10549.163,763.456 10534.126,770.45 10518.281,770.45L10414.485,770.45C10398.797,770.45 10383.893,763.594 10373.685,751.682C10363.476,739.771 10358.983,723.993 10361.385,708.49L10374.179,625.907C10378.85,595.755 10404.806,573.511 10435.317,573.511L10496.026,573.511C10526.145,573.511 10551.887,595.201 10556.997,624.883ZM10518.185,644.084L10485.169,677.1C10481.077,681.192 10474.443,681.192 10470.352,677.1L10460.989,667.737C10456.897,663.646 10456.897,657.012 10460.989,652.92C10470.018,643.891 10485.161,628.748 10494.002,619.902C10495.699,618.205 10496.43,615.769 10495.948,613.418C10495.466,611.068 10493.836,609.116 10491.609,608.224C10483.596,604.979 10474.84,603.193 10465.67,603.193C10427.463,603.193 10396.444,634.212 10396.444,672.419C10396.444,710.626 10427.463,741.645 10465.67,741.645C10503.877,741.645 10534.896,710.626 10534.896,672.419C10534.896,663.249 10533.11,654.493 10529.869,646.479C10528.976,644.25 10527.024,642.619 10524.672,642.137C10522.319,641.655 10519.882,642.386 10518.185,644.084ZM10323.418,417.171L10326.515,437.161C10331.987,472.482 10362.392,498.54 10398.135,498.54L10532.582,498.54C10567.865,498.54 10598.02,473.132 10604.006,438.36L10607.56,417.711C10608.244,413.738 10607.143,409.665 10604.55,406.578C10601.958,403.491 10598.137,401.702 10594.105,401.689L10568.061,401.604C10561.653,401.583 10556.086,406.008 10554.661,412.256L10550.796,429.201C10549.269,438.068 10541.579,444.547 10532.582,444.547L10398.135,444.547C10389.02,444.547 10381.267,437.902 10379.871,428.895L10377.426,413.111C10376.396,406.46 10370.687,401.543 10363.957,401.51L10337.023,401.375C10333.012,401.355 10329.194,403.094 10326.576,406.134C10323.958,409.173 10322.804,413.207 10323.418,417.171Z" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-15515.751862,726.774609)">
|
||||
<g transform="matrix(0.564865,0,0,0.564865,14207.096732,-899.601987)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.959532,0,0,0.959532,-7272.887866,171.062992)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538ZM10624.96,701.428L10608.01,602.96C10599.711,554.748 10557.898,519.518 10508.977,519.518L10422.144,519.518C10372.585,519.518 10330.426,555.648 10322.839,604.623L10307.572,703.169C10302.871,733.512 10311.666,764.394 10331.647,787.709C10351.628,811.024 10380.799,824.442 10411.505,824.442L10521.312,824.442C10552.325,824.442 10581.758,810.754 10601.741,787.037C10621.724,763.32 10630.221,731.992 10624.96,701.428ZM10556.997,624.883L10571.236,707.601C10573.924,723.216 10569.583,739.222 10559.373,751.339C10549.163,763.456 10534.126,770.45 10518.281,770.45L10414.485,770.45C10398.797,770.45 10383.893,763.594 10373.685,751.682C10363.476,739.771 10358.983,723.993 10361.385,708.49L10374.179,625.907C10378.85,595.755 10404.806,573.511 10435.317,573.511L10496.026,573.511C10526.145,573.511 10551.887,595.201 10556.997,624.883ZM10518.185,644.084L10485.169,677.1C10481.077,681.192 10474.443,681.192 10470.352,677.1L10460.989,667.737C10456.897,663.646 10456.897,657.012 10460.989,652.92C10470.018,643.891 10485.161,628.748 10494.002,619.902C10495.699,618.205 10496.43,615.769 10495.948,613.418C10495.466,611.068 10493.836,609.116 10491.609,608.224C10483.596,604.979 10474.84,603.193 10465.67,603.193C10427.463,603.193 10396.444,634.212 10396.444,672.419C10396.444,710.626 10427.463,741.645 10465.67,741.645C10503.877,741.645 10534.896,710.626 10534.896,672.419C10534.896,663.249 10533.11,654.493 10529.869,646.479C10528.976,644.25 10527.024,642.619 10524.672,642.137C10522.319,641.655 10519.882,642.386 10518.185,644.084ZM10323.418,417.171L10326.515,437.161C10331.987,472.482 10362.392,498.54 10398.135,498.54L10532.582,498.54C10567.865,498.54 10598.02,473.132 10604.006,438.36L10607.56,417.711C10608.244,413.738 10607.143,409.665 10604.55,406.578C10601.958,403.491 10598.137,401.702 10594.105,401.689L10568.061,401.604C10561.653,401.583 10556.086,406.008 10554.661,412.256L10550.796,429.201C10549.269,438.068 10541.579,444.547 10532.582,444.547L10398.135,444.547C10389.02,444.547 10381.267,437.902 10379.871,428.895L10377.426,413.111C10376.396,406.46 10370.687,401.543 10363.957,401.51L10337.023,401.375C10333.012,401.355 10329.194,403.094 10326.576,406.134C10323.958,409.173 10322.804,413.207 10323.418,417.171Z" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-14156.761195,726.774609)">
|
||||
<g transform="matrix(0.564865,0,0,0.564865,12848.106064,-899.601987)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:rgb(6,29,132);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.959532,0,0,0.959532,-7272.887866,171.062992)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538ZM10323.418,417.171L10326.515,437.161C10331.987,472.482 10362.392,498.54 10398.135,498.54L10532.582,498.54C10567.865,498.54 10598.02,473.132 10604.006,438.36L10607.56,417.711C10608.244,413.738 10607.143,409.665 10604.55,406.578C10601.958,403.491 10598.137,401.702 10594.105,401.689L10568.061,401.604C10561.653,401.583 10556.086,406.008 10554.661,412.256L10550.796,429.201C10549.269,438.068 10541.579,444.547 10532.582,444.547L10398.135,444.547C10389.02,444.547 10381.267,437.902 10379.871,428.895L10377.426,413.111C10376.396,406.46 10370.687,401.543 10363.957,401.51L10337.023,401.375C10333.012,401.355 10329.194,403.094 10326.576,406.134C10323.958,409.173 10322.804,413.207 10323.418,417.171ZM10624.96,701.428L10608.01,602.96C10599.711,554.748 10557.898,519.518 10508.977,519.518L10422.144,519.518C10372.585,519.518 10330.426,555.648 10322.839,604.623L10307.572,703.169C10302.871,733.512 10311.666,764.394 10331.647,787.709C10351.628,811.024 10380.799,824.442 10411.505,824.442L10521.312,824.442C10552.325,824.442 10581.758,810.754 10601.741,787.037C10621.724,763.32 10630.221,731.992 10624.96,701.428ZM10556.997,624.883L10571.236,707.601C10573.924,723.216 10569.583,739.222 10559.373,751.339C10549.163,763.456 10534.126,770.45 10518.281,770.45L10414.485,770.45C10398.797,770.45 10383.893,763.594 10373.685,751.682C10363.476,739.771 10358.983,723.993 10361.385,708.49L10374.179,625.907C10378.85,595.755 10404.806,573.511 10435.317,573.511L10496.026,573.511C10526.145,573.511 10551.887,595.201 10556.997,624.883ZM10518.185,644.084L10485.169,677.1C10481.077,681.192 10474.443,681.192 10470.352,677.1L10460.989,667.737C10456.897,663.646 10456.897,657.012 10460.989,652.92C10470.018,643.891 10485.161,628.748 10494.002,619.902C10495.699,618.205 10496.43,615.769 10495.948,613.418C10495.466,611.068 10493.836,609.116 10491.609,608.224C10483.596,604.979 10474.84,603.193 10465.67,603.193C10427.463,603.193 10396.444,634.212 10396.444,672.419C10396.444,710.626 10427.463,741.645 10465.67,741.645C10503.877,741.645 10534.896,710.626 10534.896,672.419C10534.896,663.249 10533.11,654.493 10529.869,646.479C10528.976,644.25 10527.024,642.619 10524.672,642.137C10522.319,641.655 10519.882,642.386 10518.185,644.084Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-13013.456547,726.774609)">
|
||||
<g transform="matrix(0.564865,0,0,0.564865,11704.801417,-899.601987)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.959532,0,0,0.959532,-7272.887866,171.062992)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538ZM10323.418,417.171L10326.515,437.161C10331.987,472.482 10362.392,498.54 10398.135,498.54L10532.582,498.54C10567.865,498.54 10598.02,473.132 10604.006,438.36L10607.56,417.711C10608.244,413.738 10607.143,409.665 10604.55,406.578C10601.958,403.491 10598.137,401.702 10594.105,401.689L10568.061,401.604C10561.653,401.583 10556.086,406.008 10554.661,412.256L10550.796,429.201C10549.269,438.068 10541.579,444.547 10532.582,444.547L10398.135,444.547C10389.02,444.547 10381.267,437.902 10379.871,428.895L10377.426,413.111C10376.396,406.46 10370.687,401.543 10363.957,401.51L10337.023,401.375C10333.012,401.355 10329.194,403.094 10326.576,406.134C10323.958,409.173 10322.804,413.207 10323.418,417.171ZM10624.96,701.428L10608.01,602.96C10599.711,554.748 10557.898,519.518 10508.977,519.518L10422.144,519.518C10372.585,519.518 10330.426,555.648 10322.839,604.623L10307.572,703.169C10302.871,733.512 10311.666,764.394 10331.647,787.709C10351.628,811.024 10380.799,824.442 10411.505,824.442L10521.312,824.442C10552.325,824.442 10581.758,810.754 10601.741,787.037C10621.724,763.32 10630.221,731.992 10624.96,701.428ZM10556.997,624.883L10571.236,707.601C10573.924,723.216 10569.583,739.222 10559.373,751.339C10549.163,763.456 10534.126,770.45 10518.281,770.45L10414.485,770.45C10398.797,770.45 10383.893,763.594 10373.685,751.682C10363.476,739.771 10358.983,723.993 10361.385,708.49L10374.179,625.907C10378.85,595.755 10404.806,573.511 10435.317,573.511L10496.026,573.511C10526.145,573.511 10551.887,595.201 10556.997,624.883ZM10518.185,644.084L10485.169,677.1C10481.077,681.192 10474.443,681.192 10470.352,677.1L10460.989,667.737C10456.897,663.646 10456.897,657.012 10460.989,652.92C10470.018,643.891 10485.161,628.748 10494.002,619.902C10495.699,618.205 10496.43,615.769 10495.948,613.418C10495.466,611.068 10493.836,609.116 10491.609,608.224C10483.596,604.979 10474.84,603.193 10465.67,603.193C10427.463,603.193 10396.444,634.212 10396.444,672.419C10396.444,710.626 10427.463,741.645 10465.67,741.645C10503.877,741.645 10534.896,710.626 10534.896,672.419C10534.896,663.249 10533.11,654.493 10529.869,646.479C10528.976,644.25 10527.024,642.619 10524.672,642.137C10522.319,641.655 10519.882,642.386 10518.185,644.084Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-13532.302289,726.774609)">
|
||||
<g transform="matrix(0.564865,0,0,0.564865,12223.647158,-899.601987)">
|
||||
<g transform="matrix(0.652999,0,0,0.652999,821.447853,29.128352)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.959532,0,0,0.959532,-7272.887866,171.062992)">
|
||||
<path d="M10755.151,468.538L10755.151,757.28C10755.151,836.961 10690.46,901.651 10610.78,901.651L10322.037,901.651C10242.357,901.651 10177.666,836.961 10177.666,757.28L10177.666,468.538C10177.666,388.857 10242.357,324.166 10322.037,324.166L10610.78,324.166C10690.46,324.166 10755.151,388.857 10755.151,468.538ZM10323.418,417.171L10326.515,437.161C10331.987,472.482 10362.392,498.54 10398.135,498.54L10532.582,498.54C10567.865,498.54 10598.02,473.132 10604.006,438.36L10607.56,417.711C10608.244,413.738 10607.143,409.665 10604.55,406.578C10601.958,403.491 10598.137,401.702 10594.105,401.689L10568.061,401.604C10561.653,401.583 10556.086,406.008 10554.661,412.256L10550.796,429.201C10549.269,438.068 10541.579,444.547 10532.582,444.547L10398.135,444.547C10389.02,444.547 10381.267,437.902 10379.871,428.895L10377.426,413.111C10376.396,406.46 10370.687,401.543 10363.957,401.51L10337.023,401.375C10333.012,401.355 10329.194,403.094 10326.576,406.134C10323.958,409.173 10322.804,413.207 10323.418,417.171ZM10624.96,701.428L10608.01,602.96C10599.711,554.748 10557.898,519.518 10508.977,519.518L10422.144,519.518C10372.585,519.518 10330.426,555.648 10322.839,604.623L10307.572,703.169C10302.871,733.512 10311.666,764.394 10331.647,787.709C10351.628,811.024 10380.799,824.442 10411.505,824.442L10521.312,824.442C10552.325,824.442 10581.758,810.754 10601.741,787.037C10621.724,763.32 10630.221,731.992 10624.96,701.428ZM10556.997,624.883L10571.236,707.601C10573.924,723.216 10569.583,739.222 10559.373,751.339C10549.163,763.456 10534.126,770.45 10518.281,770.45L10414.485,770.45C10398.797,770.45 10383.893,763.594 10373.685,751.682C10363.476,739.771 10358.983,723.993 10361.385,708.49L10374.179,625.907C10378.85,595.755 10404.806,573.511 10435.317,573.511L10496.026,573.511C10526.145,573.511 10551.887,595.201 10556.997,624.883ZM10518.185,644.084L10485.169,677.1C10481.077,681.192 10474.443,681.192 10470.352,677.1L10460.989,667.737C10456.897,663.646 10456.897,657.012 10460.989,652.92C10470.018,643.891 10485.161,628.748 10494.002,619.902C10495.699,618.205 10496.43,615.769 10495.948,613.418C10495.466,611.068 10493.836,609.116 10491.609,608.224C10483.596,604.979 10474.84,603.193 10465.67,603.193C10427.463,603.193 10396.444,634.212 10396.444,672.419C10396.444,710.626 10427.463,741.645 10465.67,741.645C10503.877,741.645 10534.896,710.626 10534.896,672.419C10534.896,663.249 10533.11,654.493 10529.869,646.479C10528.976,644.25 10527.024,642.619 10524.672,642.137C10522.319,641.655 10519.882,642.386 10518.185,644.084Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-12501.456547,726.774609)">
|
||||
<g transform="matrix(1,0,0,1,-151.472291,0)">
|
||||
<g transform="matrix(0.683604,0,0,0.683604,10912.013984,-1075.663646)">
|
||||
<g transform="matrix(0.764685,0,0,0.764685,1814.51336,-94.801291)">
|
||||
<g transform="matrix(0.843817,0,0,1,973.42738,670.673266)">
|
||||
<path d="M996.456,815.382C1010.891,886.141 987.579,958.668 932.752,1013.576C877.925,1068.484 797.174,1100.174 712.085,1100.174C614.422,1100.174 508.13,1100.174 410.814,1100.174C326.571,1100.174 246.534,1069.108 191.713,1015.131C136.893,961.155 112.765,889.659 125.662,819.41C139.686,743.025 154.576,661.927 167.549,591.266C188.366,477.884 304.034,394.237 440.005,394.237C516.746,394.237 601.794,394.237 678.242,394.237C812.464,394.237 927.183,475.799 949.952,587.417C964.298,657.739 980.831,738.787 996.456,815.382ZM809.991,638.17C795.972,569.452 725.344,519.237 642.709,519.237C589.643,519.237 529.429,519.237 476.147,519.237C392.435,519.237 321.222,570.735 308.406,640.54C297.616,699.31 284.584,770.291 273.304,831.73C266.715,867.62 279.042,904.148 307.05,931.725C335.058,959.302 375.949,975.174 418.99,975.174C507.403,975.174 614.937,975.174 703.769,975.174C747.242,975.174 788.498,958.983 816.51,930.93C844.521,902.878 856.431,865.823 849.056,829.672C836.451,767.879 821.939,696.744 809.991,638.17Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.843817,0,0,-1,973.42738,1410.581134)">
|
||||
<path d="M169.137,582.616C167.452,591.793 170.619,601.132 177.801,608.169C184.983,615.205 195.46,619.231 206.465,619.185C230.149,619.085 258.821,618.965 280.361,618.874C298.825,618.797 314.488,607.413 317.315,592.016C320.486,574.745 324.024,555.473 324.024,555.473C327.852,534.621 349.125,519.237 374.132,519.237L743.005,519.237C767.69,519.237 788.789,534.237 792.976,554.765C792.976,554.765 798.715,575.995 803.581,593.996C807.492,608.461 822.764,618.705 840.347,618.656C860.96,618.6 888.653,618.523 911.802,618.459C922.863,618.429 933.347,614.288 940.46,607.14C947.573,599.993 950.594,590.564 948.718,581.365C944.059,558.529 938.966,533.56 938.966,533.56C922.544,453.06 839.808,394.237 743.005,394.237L374.132,394.237C276.068,394.237 192.647,454.564 177.634,536.336C177.634,536.336 173.216,560.398 169.137,582.616Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.923041,-0,0,0.923041,854.504081,621.345248)">
|
||||
<path d="M771.961,792.978C776.219,788.719 782.332,786.884 788.231,788.093C794.131,789.302 799.029,793.394 801.268,798.984C809.395,819.084 813.877,841.045 813.877,864.045C813.877,959.873 736.076,1037.674 640.248,1037.674C544.419,1037.674 466.619,959.873 466.619,864.045C466.619,768.216 544.419,690.416 640.248,690.416C663.247,690.416 685.208,694.897 705.305,703.034C710.892,705.272 714.981,710.167 716.189,716.063C717.398,721.96 715.564,728.068 711.308,732.324C689.133,754.513 651.152,792.493 628.507,815.139C618.244,825.402 618.244,842.041 628.507,852.303C635.961,859.758 644.535,868.331 651.989,875.786C662.252,886.048 678.891,886.048 689.153,875.786C711.799,853.14 749.779,815.16 771.961,792.978Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.368856,0,0,0.368856,11808.280456,-883.148415)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:none;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-11884.181719,726.774609)">
|
||||
<g transform="matrix(1,0,0,1,86.762524,160.29105)">
|
||||
<g transform="matrix(0.30616,0,0,0.30616,11159.078973,-901.97185)">
|
||||
<g transform="matrix(0.764685,0,0,0.764685,1814.51336,-94.801291)">
|
||||
<g transform="matrix(0.843817,0,0,1,973.42738,670.673266)">
|
||||
<path d="M996.456,815.382C1010.891,886.141 987.579,958.668 932.752,1013.576C877.925,1068.484 797.174,1100.174 712.085,1100.174C614.422,1100.174 508.13,1100.174 410.814,1100.174C326.571,1100.174 246.534,1069.108 191.713,1015.131C136.893,961.155 112.765,889.659 125.662,819.41C139.686,743.025 154.576,661.927 167.549,591.266C188.366,477.884 304.034,394.237 440.005,394.237C516.746,394.237 601.794,394.237 678.242,394.237C812.464,394.237 927.183,475.799 949.952,587.417C964.298,657.739 980.831,738.787 996.456,815.382ZM809.991,638.17C795.972,569.452 725.344,519.237 642.709,519.237C589.643,519.237 529.429,519.237 476.147,519.237C392.435,519.237 321.222,570.735 308.406,640.54C297.616,699.31 284.584,770.291 273.304,831.73C266.715,867.62 279.042,904.148 307.05,931.725C335.058,959.302 375.949,975.174 418.99,975.174C507.403,975.174 614.937,975.174 703.769,975.174C747.242,975.174 788.498,958.983 816.51,930.93C844.521,902.878 856.431,865.823 849.056,829.672C836.451,767.879 821.939,696.744 809.991,638.17Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.843817,0,0,-1,973.42738,1410.581134)">
|
||||
<path d="M169.137,582.616C167.452,591.793 170.619,601.132 177.801,608.169C184.983,615.205 195.46,619.231 206.465,619.185C230.149,619.085 258.821,618.965 280.361,618.874C298.825,618.797 314.488,607.413 317.315,592.016C320.486,574.745 324.024,555.473 324.024,555.473C327.852,534.621 349.125,519.237 374.132,519.237L743.005,519.237C767.69,519.237 788.789,534.237 792.976,554.765C792.976,554.765 798.715,575.995 803.581,593.996C807.492,608.461 822.764,618.705 840.347,618.656C860.96,618.6 888.653,618.523 911.802,618.459C922.863,618.429 933.347,614.288 940.46,607.14C947.573,599.993 950.594,590.564 948.718,581.365C944.059,558.529 938.966,533.56 938.966,533.56C922.544,453.06 839.808,394.237 743.005,394.237L374.132,394.237C276.068,394.237 192.647,454.564 177.634,536.336C177.634,536.336 173.216,560.398 169.137,582.616Z" style="fill:rgb(23,66,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.923041,-0,0,0.923041,854.504081,621.345248)">
|
||||
<path d="M771.961,792.978C776.219,788.719 782.332,786.884 788.231,788.093C794.131,789.302 799.029,793.394 801.268,798.984C809.395,819.084 813.877,841.045 813.877,864.045C813.877,959.873 736.076,1037.674 640.248,1037.674C544.419,1037.674 466.619,959.873 466.619,864.045C466.619,768.216 544.419,690.416 640.248,690.416C663.247,690.416 685.208,694.897 705.305,703.034C710.892,705.272 714.981,710.167 716.189,716.063C717.398,721.96 715.564,728.068 711.308,732.324C689.133,754.513 651.152,792.493 628.507,815.139C618.244,825.402 618.244,842.041 628.507,852.303C635.961,859.758 644.535,868.331 651.989,875.786C662.252,886.048 678.891,886.048 689.153,875.786C711.799,853.14 749.779,815.16 771.961,792.978Z" style="fill:rgb(0,214,156);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.368856,0,0,0.368856,10952.770812,-1043.439465)">
|
||||
<rect x="2289.913" y="423.943" width="1388.075" height="1388.075" style="fill:none;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -1,34 +1,34 @@
|
||||
**/dgph
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
*.perspectivev3
|
||||
**/*sync/
|
||||
.sconsign.dblite
|
||||
.tags*
|
||||
**/.vagrant/
|
||||
**/DerivedData/
|
||||
Icon?
|
||||
**/Pods/
|
||||
**/.symlinks/
|
||||
profile
|
||||
xcuserdata
|
||||
**/.generated/
|
||||
Flutter/App.framework
|
||||
Flutter/Flutter.framework
|
||||
Flutter/Flutter.podspec
|
||||
Flutter/Generated.xcconfig
|
||||
Flutter/ephemeral/
|
||||
Flutter/app.flx
|
||||
Flutter/app.zip
|
||||
Flutter/flutter_assets/
|
||||
Flutter/flutter_export_environment.sh
|
||||
ServiceDefinitions.json
|
||||
Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.pbxuser
|
||||
!default.perspectivev3
|
||||
**/dgph
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
*.perspectivev3
|
||||
**/*sync/
|
||||
.sconsign.dblite
|
||||
.tags*
|
||||
**/.vagrant/
|
||||
**/DerivedData/
|
||||
Icon?
|
||||
**/Pods/
|
||||
**/.symlinks/
|
||||
profile
|
||||
xcuserdata
|
||||
**/.generated/
|
||||
Flutter/App.framework
|
||||
Flutter/Flutter.framework
|
||||
Flutter/Flutter.podspec
|
||||
Flutter/Generated.xcconfig
|
||||
Flutter/ephemeral/
|
||||
Flutter/app.flx
|
||||
Flutter/app.zip
|
||||
Flutter/flutter_assets/
|
||||
Flutter/flutter_export_environment.sh
|
||||
ServiceDefinitions.json
|
||||
Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.pbxuser
|
||||
!default.perspectivev3
|
||||
@@ -1,26 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>13.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>13.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1 +1 @@
|
||||
#include "Generated.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
@@ -1 +1 @@
|
||||
#include "Generated.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,101 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "331C8080294A63A400263BE5"
|
||||
BuildableName = "RunnerTests.xctest"
|
||||
BlueprintName = "RunnerTests"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
enableGPUValidationMode = "1"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "331C8080294A63A400263BE5"
|
||||
BuildableName = "RunnerTests.xctest"
|
||||
BlueprintName = "RunnerTests"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
enableGPUValidationMode = "1"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,13 +1,13 @@
|
||||
import Flutter
|
||||
import UIKit
|
||||
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
}
|
||||
import Flutter
|
||||
import UIKit
|
||||
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
}
|
||||
@@ -1,122 +1,122 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
# Launch Screen Assets
|
||||
|
||||
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
|
||||
|
||||
# Launch Screen Assets
|
||||
|
||||
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
|
||||
|
||||
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
|
||||
@@ -1,37 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
</resources>
|
||||
</document>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -1,26 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -1 +1 @@
|
||||
#import "GeneratedPluginRegistrant.h"
|
||||
#import "GeneratedPluginRegistrant.h"
|
||||
@@ -1,12 +1,12 @@
|
||||
import Flutter
|
||||
import UIKit
|
||||
import XCTest
|
||||
|
||||
class RunnerTests: XCTestCase {
|
||||
|
||||
func testExample() {
|
||||
// If you add code to the Runner application, consider adding tests here.
|
||||
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
|
||||
}
|
||||
|
||||
}
|
||||
import Flutter
|
||||
import UIKit
|
||||
import XCTest
|
||||
|
||||
class RunnerTests: XCTestCase {
|
||||
|
||||
func testExample() {
|
||||
// If you add code to the Runner application, consider adding tests here.
|
||||
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +1,93 @@
|
||||
import 'package:path/path.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
import '../models/registered_device.dart';
|
||||
|
||||
const _tableName = 'siab_devices';
|
||||
|
||||
class SiabDatabase {
|
||||
static Database? _db;
|
||||
|
||||
static Future<Database> get database async {
|
||||
if (_db != null) return _db!;
|
||||
_db = await _init();
|
||||
return _db!;
|
||||
}
|
||||
|
||||
static Future<Database> _init() async {
|
||||
final dbPath = await getDatabasesPath();
|
||||
final path = join(dbPath, 'siab_devices.db');
|
||||
return openDatabase(
|
||||
path,
|
||||
version: 2,
|
||||
onCreate: (db, version) async {
|
||||
await db.execute('''
|
||||
CREATE TABLE $_tableName (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
uuid TEXT NOT NULL UNIQUE,
|
||||
label TEXT NOT NULL
|
||||
)
|
||||
''');
|
||||
},
|
||||
onUpgrade: (db, oldVersion, newVersion) async {
|
||||
// Simple destructive migration: drop old table and recreate with new schema.
|
||||
if (oldVersion < 2) {
|
||||
await db.execute('DROP TABLE IF EXISTS $_tableName');
|
||||
await db.execute('''
|
||||
CREATE TABLE $_tableName (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
uuid TEXT NOT NULL UNIQUE,
|
||||
label TEXT NOT NULL
|
||||
)
|
||||
''');
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<int> insert(RegisteredDevice device) async {
|
||||
final db = await database;
|
||||
return db.insert(
|
||||
_tableName,
|
||||
device.toMap(),
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<RegisteredDevice>> getAll() async {
|
||||
final db = await database;
|
||||
final maps = await db.query(_tableName, orderBy: 'label ASC');
|
||||
return maps.map(RegisteredDevice.fromMap).toList();
|
||||
}
|
||||
|
||||
Future<RegisteredDevice?> getByUuid(String uuid) async {
|
||||
final db = await database;
|
||||
final maps = await db.query(
|
||||
_tableName,
|
||||
where: 'uuid = ?',
|
||||
whereArgs: [uuid],
|
||||
);
|
||||
if (maps.isEmpty) return null;
|
||||
return RegisteredDevice.fromMap(maps.first);
|
||||
}
|
||||
|
||||
Future<int> update(RegisteredDevice device) async {
|
||||
if (device.id == null) return 0;
|
||||
final db = await database;
|
||||
return db.update(
|
||||
_tableName,
|
||||
device.toMap(),
|
||||
where: 'id = ?',
|
||||
whereArgs: [device.id],
|
||||
);
|
||||
}
|
||||
|
||||
Future<int> delete(int id) async {
|
||||
final db = await database;
|
||||
return db.delete(_tableName, where: 'id = ?', whereArgs: [id]);
|
||||
}
|
||||
|
||||
Future<int> deleteByUuid(String uuid) async {
|
||||
final db = await database;
|
||||
return db.delete(_tableName, where: 'uuid = ?', whereArgs: [uuid]);
|
||||
}
|
||||
}
|
||||
import 'package:path/path.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
import '../models/registered_device.dart';
|
||||
|
||||
const _tableName = 'siab_devices';
|
||||
|
||||
class SiabDatabase {
|
||||
static Database? _db;
|
||||
|
||||
static Future<Database> get database async {
|
||||
if (_db != null) return _db!;
|
||||
_db = await _init();
|
||||
return _db!;
|
||||
}
|
||||
|
||||
static Future<Database> _init() async {
|
||||
final dbPath = await getDatabasesPath();
|
||||
final path = join(dbPath, 'siab_devices.db');
|
||||
return openDatabase(
|
||||
path,
|
||||
version: 2,
|
||||
onCreate: (db, version) async {
|
||||
await db.execute('''
|
||||
CREATE TABLE $_tableName (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
uuid TEXT NOT NULL UNIQUE,
|
||||
label TEXT NOT NULL
|
||||
)
|
||||
''');
|
||||
},
|
||||
onUpgrade: (db, oldVersion, newVersion) async {
|
||||
// Simple destructive migration: drop old table and recreate with new schema.
|
||||
if (oldVersion < 2) {
|
||||
await db.execute('DROP TABLE IF EXISTS $_tableName');
|
||||
await db.execute('''
|
||||
CREATE TABLE $_tableName (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
uuid TEXT NOT NULL UNIQUE,
|
||||
label TEXT NOT NULL
|
||||
)
|
||||
''');
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<int> insert(RegisteredDevice device) async {
|
||||
final db = await database;
|
||||
return db.insert(
|
||||
_tableName,
|
||||
device.toMap(),
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<RegisteredDevice>> getAll() async {
|
||||
final db = await database;
|
||||
final maps = await db.query(_tableName, orderBy: 'label ASC');
|
||||
return maps.map(RegisteredDevice.fromMap).toList();
|
||||
}
|
||||
|
||||
Future<RegisteredDevice?> getByUuid(String uuid) async {
|
||||
final db = await database;
|
||||
final maps = await db.query(
|
||||
_tableName,
|
||||
where: 'uuid = ?',
|
||||
whereArgs: [uuid],
|
||||
);
|
||||
if (maps.isEmpty) return null;
|
||||
return RegisteredDevice.fromMap(maps.first);
|
||||
}
|
||||
|
||||
Future<int> update(RegisteredDevice device) async {
|
||||
if (device.id == null) return 0;
|
||||
final db = await database;
|
||||
return db.update(
|
||||
_tableName,
|
||||
device.toMap(),
|
||||
where: 'id = ?',
|
||||
whereArgs: [device.id],
|
||||
);
|
||||
}
|
||||
|
||||
Future<int> delete(int id) async {
|
||||
final db = await database;
|
||||
return db.delete(_tableName, where: 'id = ?', whereArgs: [id]);
|
||||
}
|
||||
|
||||
Future<int> deleteByUuid(String uuid) async {
|
||||
final db = await database;
|
||||
return db.delete(_tableName, where: 'uuid = ?', whereArgs: [uuid]);
|
||||
}
|
||||
}
|
||||
@@ -1,97 +1,97 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'services/ble_service.dart';
|
||||
import 'screens/main_shell.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const SIABApp());
|
||||
}
|
||||
|
||||
class SIABApp extends StatelessWidget {
|
||||
const SIABApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = ColorScheme.fromSeed(
|
||||
seedColor: const Color(0xFF2563EB),
|
||||
brightness: Brightness.light,
|
||||
);
|
||||
|
||||
return ChangeNotifierProvider(
|
||||
create: (_) => BLEService(),
|
||||
child: MaterialApp(
|
||||
title: 'SIAB Scale',
|
||||
theme: ThemeData(
|
||||
colorScheme: colorScheme,
|
||||
scaffoldBackgroundColor: const Color(0xFFF4F8FF),
|
||||
useMaterial3: true,
|
||||
appBarTheme: const AppBarTheme(
|
||||
centerTitle: false,
|
||||
backgroundColor: Color(0xFFF8FBFF),
|
||||
foregroundColor: Color(0xFF0F172A),
|
||||
elevation: 0,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
),
|
||||
cardTheme: CardThemeData(
|
||||
color: Colors.white,
|
||||
elevation: 0,
|
||||
margin: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
),
|
||||
),
|
||||
filledButtonTheme: FilledButtonThemeData(
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF2563EB),
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
),
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF2563EB),
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
),
|
||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: const Color(0xFF2563EB),
|
||||
side: const BorderSide(color: Color(0x663B82F6)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
),
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: const Color(0xFF2563EB),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
behavior: SnackBarBehavior.floating,
|
||||
backgroundColor: const Color(0xFF0F172A),
|
||||
contentTextStyle: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
),
|
||||
themeMode: ThemeMode.light,
|
||||
home: const MainShell(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'services/ble_service.dart';
|
||||
import 'screens/main_shell.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const SIABApp());
|
||||
}
|
||||
|
||||
class SIABApp extends StatelessWidget {
|
||||
const SIABApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = ColorScheme.fromSeed(
|
||||
seedColor: const Color(0xFF2563EB),
|
||||
brightness: Brightness.light,
|
||||
);
|
||||
|
||||
return ChangeNotifierProvider(
|
||||
create: (_) => BLEService(),
|
||||
child: MaterialApp(
|
||||
title: 'SIAB Scale',
|
||||
theme: ThemeData(
|
||||
colorScheme: colorScheme,
|
||||
scaffoldBackgroundColor: const Color(0xFFF4F8FF),
|
||||
useMaterial3: true,
|
||||
appBarTheme: const AppBarTheme(
|
||||
centerTitle: false,
|
||||
backgroundColor: Color(0xFFF8FBFF),
|
||||
foregroundColor: Color(0xFF0F172A),
|
||||
elevation: 0,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
),
|
||||
cardTheme: CardThemeData(
|
||||
color: Colors.white,
|
||||
elevation: 0,
|
||||
margin: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
),
|
||||
),
|
||||
filledButtonTheme: FilledButtonThemeData(
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF2563EB),
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
),
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF2563EB),
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
),
|
||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: const Color(0xFF2563EB),
|
||||
side: const BorderSide(color: Color(0x663B82F6)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
),
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: const Color(0xFF2563EB),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
behavior: SnackBarBehavior.floating,
|
||||
backgroundColor: const Color(0xFF0F172A),
|
||||
contentTextStyle: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
),
|
||||
themeMode: ThemeMode.light,
|
||||
home: const MainShell(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +1,41 @@
|
||||
/// A SIAB device registered in local SQLite with a user-assigned label.
|
||||
/// Stores only a user label (\"Label ID\") and the device UUID.
|
||||
class RegisteredDevice {
|
||||
final int? id;
|
||||
final String uuid;
|
||||
final String label;
|
||||
|
||||
RegisteredDevice({
|
||||
this.id,
|
||||
required this.uuid,
|
||||
required this.label,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
if (id != null) 'id': id,
|
||||
'uuid': uuid,
|
||||
'label': label,
|
||||
};
|
||||
}
|
||||
|
||||
static RegisteredDevice fromMap(Map<String, dynamic> map) {
|
||||
return RegisteredDevice(
|
||||
id: map['id'] as int?,
|
||||
uuid: map['uuid'] as String,
|
||||
label: map['label'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
RegisteredDevice copyWith({
|
||||
int? id,
|
||||
String? uuid,
|
||||
String? label,
|
||||
}) {
|
||||
return RegisteredDevice(
|
||||
id: id ?? this.id,
|
||||
uuid: uuid ?? this.uuid,
|
||||
label: label ?? this.label,
|
||||
);
|
||||
}
|
||||
}
|
||||
/// A SIAB device registered in local SQLite with a user-assigned label.
|
||||
/// Stores only a user label (\"Label ID\") and the device UUID.
|
||||
class RegisteredDevice {
|
||||
final int? id;
|
||||
final String uuid;
|
||||
final String label;
|
||||
|
||||
RegisteredDevice({
|
||||
this.id,
|
||||
required this.uuid,
|
||||
required this.label,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
if (id != null) 'id': id,
|
||||
'uuid': uuid,
|
||||
'label': label,
|
||||
};
|
||||
}
|
||||
|
||||
static RegisteredDevice fromMap(Map<String, dynamic> map) {
|
||||
return RegisteredDevice(
|
||||
id: map['id'] as int?,
|
||||
uuid: map['uuid'] as String,
|
||||
label: map['label'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
RegisteredDevice copyWith({
|
||||
int? id,
|
||||
String? uuid,
|
||||
String? label,
|
||||
}) {
|
||||
return RegisteredDevice(
|
||||
id: id ?? this.id,
|
||||
uuid: uuid ?? this.uuid,
|
||||
label: label ?? this.label,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,318 +1,318 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../database/siab_database.dart';
|
||||
import '../models/registered_device.dart';
|
||||
import '../services/ble_service.dart';
|
||||
import '../siab_config.dart';
|
||||
|
||||
class DevicesScreen extends StatefulWidget {
|
||||
const DevicesScreen({super.key});
|
||||
|
||||
@override
|
||||
State<DevicesScreen> createState() => _DevicesScreenState();
|
||||
}
|
||||
|
||||
class _DevicesScreenState extends State<DevicesScreen> {
|
||||
final _db = SiabDatabase();
|
||||
List<RegisteredDevice> _saved = [];
|
||||
List<SiabScanResult> _scanResults = [];
|
||||
bool _loading = false;
|
||||
|
||||
Future<void> _loadSaved() async {
|
||||
setState(() => _loading = true);
|
||||
_saved = await _db.getAll();
|
||||
setState(() => _loading = false);
|
||||
}
|
||||
|
||||
Future<void> _scan() async {
|
||||
final ble = context.read<BLEService>();
|
||||
setState(() => _scanResults = []);
|
||||
final list = await ble.scanForAllSiabDevices();
|
||||
setState(() => _scanResults = list);
|
||||
}
|
||||
|
||||
Future<void> _register( SiabScanResult result, String label) async {
|
||||
await _db.insert(RegisteredDevice(
|
||||
uuid: result.address,
|
||||
label: label.isEmpty ? result.address : label,
|
||||
));
|
||||
await _loadSaved();
|
||||
}
|
||||
|
||||
Future<void> _connectToScanResult(SiabScanResult result) async {
|
||||
final ble = context.read<BLEService>();
|
||||
final ok = await ble.connectToDevice(result.device);
|
||||
if (mounted && !ok) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Connection failed'), backgroundColor: Colors.red),
|
||||
);
|
||||
} else if (mounted && ok) {
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
if (mounted && ble.packetCount == 0) ble.tryStartCommands();
|
||||
await _loadSaved();
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Connected'), backgroundColor: Colors.green),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _connectToSaved(RegisteredDevice device) async {
|
||||
final ble = context.read<BLEService>();
|
||||
final ok = await ble.connectToAddress(device.uuid);
|
||||
if (mounted && !ok) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Device not found or connection failed'), backgroundColor: Colors.red),
|
||||
);
|
||||
} else if (mounted && ok) {
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
if (mounted && ble.packetCount == 0) ble.tryStartCommands();
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Connected'), backgroundColor: Colors.green),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _unregisterDevice(RegisteredDevice device) async {
|
||||
final confirmed = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: const Text('Unregister device'),
|
||||
content: Text(
|
||||
'Remove "${device.label}" (${device.uuid}) from registered devices?',
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx, false),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => Navigator.pop(ctx, true),
|
||||
child: const Text('Unregister'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (confirmed != true) return;
|
||||
|
||||
if (device.id != null) {
|
||||
await _db.delete(device.id!);
|
||||
} else {
|
||||
await _db.deleteByUuid(device.uuid);
|
||||
}
|
||||
await _loadSaved();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadSaved();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('SIAB SCALE'),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: _loading ? null : _loadSaved,
|
||||
icon: const Icon(Icons.refresh),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Consumer<BLEService>(
|
||||
builder: (context, ble, _) {
|
||||
return ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
// Scan section at top
|
||||
const Text('Daftar Timbangan (scan)', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 8),
|
||||
OutlinedButton.icon(
|
||||
onPressed: ble.isScanning ? null : () async { await _scan(); },
|
||||
icon: ble.isScanning
|
||||
? const SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Icon(Icons.bluetooth_searching, size: 20),
|
||||
label: Text(ble.isScanning ? 'Scanning...' : 'Scan Timbangan'),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
if (_scanResults.isEmpty && !ble.isScanning)
|
||||
const Card(child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Text('Tap "Scan Timbangan" lihat melihat timbangan di sekitar.'),
|
||||
))
|
||||
else
|
||||
..._scanResults.map((r) {
|
||||
RegisteredDevice? registered;
|
||||
for (final d in _saved) {
|
||||
if (d.uuid == r.address) { registered = d; break; }
|
||||
}
|
||||
final labelId = registered?.label;
|
||||
final hasLabel = labelId != null && labelId.isNotEmpty;
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_ListRow(label: 'NAMA', value: labelId ?? '—'),
|
||||
_ListRow(label: 'ID', value: r.device.remoteId.toString()),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (!hasLabel)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: TextButton.icon(
|
||||
onPressed: () => _showRegisterDialog(r),
|
||||
icon: const Icon(Icons.app_registration, size: 18),
|
||||
label: const Text('Register'),
|
||||
),
|
||||
),
|
||||
TextButton.icon(
|
||||
onPressed: ble.isConnecting ? null : () => _connectToScanResult(r),
|
||||
icon: const Icon(Icons.link, size: 18),
|
||||
label: const Text('Connect'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Registered devices below scan
|
||||
const Text('Registered devices (saved)', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 8),
|
||||
if (_loading)
|
||||
const Center(child: CircularProgressIndicator())
|
||||
else if (_saved.isEmpty)
|
||||
const Card(child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Text('No registered devices. Scan and register above.'),
|
||||
))
|
||||
else
|
||||
..._saved.map((d) => Card(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_ListRow(label: 'NAMA', value: d.label),
|
||||
_ListRow(label: 'ID', value: d.uuid),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton.icon(
|
||||
onPressed: () => _unregisterDevice(d),
|
||||
icon: const Icon(Icons.delete_outline, size: 18),
|
||||
label: const Text('Unregister'),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
if (ble.isConnected && ble.deviceAddress == d.uuid)
|
||||
const Icon(Icons.bluetooth_connected, color: Colors.green, size: 28)
|
||||
else
|
||||
TextButton.icon(
|
||||
onPressed: ble.isConnecting ? null : () => _connectToSaved(d),
|
||||
icon: const Icon(Icons.link, size: 18),
|
||||
label: const Text('Connect'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showRegisterDialog(SiabScanResult result) {
|
||||
final controller = TextEditingController(
|
||||
text: result.name.isNotEmpty ? result.name : SiabConfig.deviceName,
|
||||
);
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: const Text('Register device'),
|
||||
content: TextField(
|
||||
controller: controller,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Nama',
|
||||
hintText: 'contoh : Scale 1, TIMBANGAN 1',
|
||||
),
|
||||
autofocus: true,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () async {
|
||||
final label = controller.text.trim();
|
||||
await _register(result, label.isEmpty ? result.address : label);
|
||||
if (mounted) Navigator.pop(ctx);
|
||||
},
|
||||
child: const Text('Save'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ListRow extends StatelessWidget {
|
||||
final String label;
|
||||
final String value;
|
||||
|
||||
const _ListRow({required this.label, required this.value});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 110,
|
||||
child: Text(
|
||||
'$label:',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.8),
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SelectableText(
|
||||
value,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../database/siab_database.dart';
|
||||
import '../models/registered_device.dart';
|
||||
import '../services/ble_service.dart';
|
||||
import '../siab_config.dart';
|
||||
|
||||
class DevicesScreen extends StatefulWidget {
|
||||
const DevicesScreen({super.key});
|
||||
|
||||
@override
|
||||
State<DevicesScreen> createState() => _DevicesScreenState();
|
||||
}
|
||||
|
||||
class _DevicesScreenState extends State<DevicesScreen> {
|
||||
final _db = SiabDatabase();
|
||||
List<RegisteredDevice> _saved = [];
|
||||
List<SiabScanResult> _scanResults = [];
|
||||
bool _loading = false;
|
||||
|
||||
Future<void> _loadSaved() async {
|
||||
setState(() => _loading = true);
|
||||
_saved = await _db.getAll();
|
||||
setState(() => _loading = false);
|
||||
}
|
||||
|
||||
Future<void> _scan() async {
|
||||
final ble = context.read<BLEService>();
|
||||
setState(() => _scanResults = []);
|
||||
final list = await ble.scanForAllSiabDevices();
|
||||
setState(() => _scanResults = list);
|
||||
}
|
||||
|
||||
Future<void> _register( SiabScanResult result, String label) async {
|
||||
await _db.insert(RegisteredDevice(
|
||||
uuid: result.address,
|
||||
label: label.isEmpty ? result.address : label,
|
||||
));
|
||||
await _loadSaved();
|
||||
}
|
||||
|
||||
Future<void> _connectToScanResult(SiabScanResult result) async {
|
||||
final ble = context.read<BLEService>();
|
||||
final ok = await ble.connectToDevice(result.device);
|
||||
if (mounted && !ok) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Connection failed'), backgroundColor: Colors.red),
|
||||
);
|
||||
} else if (mounted && ok) {
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
if (mounted && ble.packetCount == 0) ble.tryStartCommands();
|
||||
await _loadSaved();
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Connected'), backgroundColor: Colors.green),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _connectToSaved(RegisteredDevice device) async {
|
||||
final ble = context.read<BLEService>();
|
||||
final ok = await ble.connectToAddress(device.uuid);
|
||||
if (mounted && !ok) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Device not found or connection failed'), backgroundColor: Colors.red),
|
||||
);
|
||||
} else if (mounted && ok) {
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
if (mounted && ble.packetCount == 0) ble.tryStartCommands();
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Connected'), backgroundColor: Colors.green),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _unregisterDevice(RegisteredDevice device) async {
|
||||
final confirmed = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: const Text('Unregister device'),
|
||||
content: Text(
|
||||
'Remove "${device.label}" (${device.uuid}) from registered devices?',
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx, false),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => Navigator.pop(ctx, true),
|
||||
child: const Text('Unregister'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (confirmed != true) return;
|
||||
|
||||
if (device.id != null) {
|
||||
await _db.delete(device.id!);
|
||||
} else {
|
||||
await _db.deleteByUuid(device.uuid);
|
||||
}
|
||||
await _loadSaved();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadSaved();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('SIAB SCALE'),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: _loading ? null : _loadSaved,
|
||||
icon: const Icon(Icons.refresh),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Consumer<BLEService>(
|
||||
builder: (context, ble, _) {
|
||||
return ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
// Scan section at top
|
||||
const Text('Daftar Timbangan (scan)', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 8),
|
||||
OutlinedButton.icon(
|
||||
onPressed: ble.isScanning ? null : () async { await _scan(); },
|
||||
icon: ble.isScanning
|
||||
? const SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Icon(Icons.bluetooth_searching, size: 20),
|
||||
label: Text(ble.isScanning ? 'Scanning...' : 'Scan Timbangan'),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
if (_scanResults.isEmpty && !ble.isScanning)
|
||||
const Card(child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Text('Tap "Scan Timbangan" lihat melihat timbangan di sekitar.'),
|
||||
))
|
||||
else
|
||||
..._scanResults.map((r) {
|
||||
RegisteredDevice? registered;
|
||||
for (final d in _saved) {
|
||||
if (d.uuid == r.address) { registered = d; break; }
|
||||
}
|
||||
final labelId = registered?.label;
|
||||
final hasLabel = labelId != null && labelId.isNotEmpty;
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_ListRow(label: 'NAMA', value: labelId ?? '—'),
|
||||
_ListRow(label: 'ID', value: r.device.remoteId.toString()),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (!hasLabel)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: TextButton.icon(
|
||||
onPressed: () => _showRegisterDialog(r),
|
||||
icon: const Icon(Icons.app_registration, size: 18),
|
||||
label: const Text('Register'),
|
||||
),
|
||||
),
|
||||
TextButton.icon(
|
||||
onPressed: ble.isConnecting ? null : () => _connectToScanResult(r),
|
||||
icon: const Icon(Icons.link, size: 18),
|
||||
label: const Text('Connect'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Registered devices below scan
|
||||
const Text('Registered devices (saved)', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 8),
|
||||
if (_loading)
|
||||
const Center(child: CircularProgressIndicator())
|
||||
else if (_saved.isEmpty)
|
||||
const Card(child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Text('No registered devices. Scan and register above.'),
|
||||
))
|
||||
else
|
||||
..._saved.map((d) => Card(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_ListRow(label: 'NAMA', value: d.label),
|
||||
_ListRow(label: 'ID', value: d.uuid),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton.icon(
|
||||
onPressed: () => _unregisterDevice(d),
|
||||
icon: const Icon(Icons.delete_outline, size: 18),
|
||||
label: const Text('Unregister'),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
if (ble.isConnected && ble.deviceAddress == d.uuid)
|
||||
const Icon(Icons.bluetooth_connected, color: Colors.green, size: 28)
|
||||
else
|
||||
TextButton.icon(
|
||||
onPressed: ble.isConnecting ? null : () => _connectToSaved(d),
|
||||
icon: const Icon(Icons.link, size: 18),
|
||||
label: const Text('Connect'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showRegisterDialog(SiabScanResult result) {
|
||||
final controller = TextEditingController(
|
||||
text: result.name.isNotEmpty ? result.name : SiabConfig.deviceName,
|
||||
);
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: const Text('Register device'),
|
||||
content: TextField(
|
||||
controller: controller,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Nama',
|
||||
hintText: 'contoh : Scale 1, TIMBANGAN 1',
|
||||
),
|
||||
autofocus: true,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () async {
|
||||
final label = controller.text.trim();
|
||||
await _register(result, label.isEmpty ? result.address : label);
|
||||
if (ctx.mounted) Navigator.pop(ctx);
|
||||
},
|
||||
child: const Text('Save'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ListRow extends StatelessWidget {
|
||||
final String label;
|
||||
final String value;
|
||||
|
||||
const _ListRow({required this.label, required this.value});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 110,
|
||||
child: Text(
|
||||
'$label:',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.8),
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SelectableText(
|
||||
value,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,143 +1,144 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../services/ble_service.dart';
|
||||
import '../widgets/data_packet_card.dart';
|
||||
import '../widgets/statistics_card.dart';
|
||||
import '../widgets/connection_card.dart';
|
||||
|
||||
class HomeScreen extends StatefulWidget {
|
||||
const HomeScreen({super.key});
|
||||
|
||||
@override
|
||||
State<HomeScreen> createState() => _HomeScreenState();
|
||||
}
|
||||
|
||||
class _HomeScreenState extends State<HomeScreen> {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('SIAB Scale'),
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
actions: [
|
||||
Consumer<BLEService>(
|
||||
builder: (context, ble, _) {
|
||||
if (ble.isConnected) {
|
||||
return IconButton(
|
||||
icon: const Icon(Icons.delete_outline),
|
||||
tooltip: 'Clear Data',
|
||||
onPressed: () {
|
||||
ble.clearData();
|
||||
},
|
||||
);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Consumer<BLEService>(
|
||||
builder: (context, ble, _) {
|
||||
return Column(
|
||||
children: [
|
||||
// Connection Card
|
||||
ConnectionCard(ble: ble),
|
||||
|
||||
// Statistics Card
|
||||
if (ble.isConnected) StatisticsCard(ble: ble),
|
||||
|
||||
// Data Packets List
|
||||
Expanded(
|
||||
child: ble.isConnected && ble.dataPackets.isNotEmpty
|
||||
? ListView.builder(
|
||||
controller: _scrollController,
|
||||
padding: const EdgeInsets.all(8),
|
||||
itemCount: ble.dataPackets.length,
|
||||
reverse: true, // Show newest first
|
||||
itemBuilder: (context, index) {
|
||||
final packet = ble.dataPackets[ble.dataPackets.length - 1 - index];
|
||||
return DataPacketCard(packet: packet);
|
||||
},
|
||||
)
|
||||
: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
ble.isConnected
|
||||
? Icons.bluetooth_connected
|
||||
: Icons.bluetooth_disabled,
|
||||
size: 64,
|
||||
color: Colors.grey,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
ble.isConnected
|
||||
? 'Waiting for data...'
|
||||
: 'Not connected',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
if (ble.isConnected) ...[
|
||||
const SizedBox(height: 8),
|
||||
const Text(
|
||||
'Data packets will appear here',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
floatingActionButton: Consumer<BLEService>(
|
||||
builder: (context, ble, _) {
|
||||
if (ble.isConnecting || ble.isScanning) {
|
||||
return const FloatingActionButton(
|
||||
onPressed: null,
|
||||
child: CircularProgressIndicator(color: Colors.white),
|
||||
);
|
||||
}
|
||||
|
||||
if (ble.isConnected) {
|
||||
return FloatingActionButton(
|
||||
onPressed: () async {
|
||||
await ble.disconnect();
|
||||
ble.clearData();
|
||||
},
|
||||
backgroundColor: Colors.red,
|
||||
child: const Icon(Icons.bluetooth_disabled),
|
||||
);
|
||||
}
|
||||
|
||||
return FloatingActionButton(
|
||||
onPressed: () async {
|
||||
final success = await ble.autoConnect();
|
||||
if (!success && mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Koneksi ke timbangan gagal'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: const Icon(Icons.bluetooth_searching),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../services/ble_service.dart';
|
||||
import '../widgets/data_packet_card.dart';
|
||||
import '../widgets/statistics_card.dart';
|
||||
import '../widgets/connection_card.dart';
|
||||
|
||||
class HomeScreen extends StatefulWidget {
|
||||
const HomeScreen({super.key});
|
||||
|
||||
@override
|
||||
State<HomeScreen> createState() => _HomeScreenState();
|
||||
}
|
||||
|
||||
class _HomeScreenState extends State<HomeScreen> {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('SIAB Scale'),
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
actions: [
|
||||
Consumer<BLEService>(
|
||||
builder: (context, ble, _) {
|
||||
if (ble.isConnected) {
|
||||
return IconButton(
|
||||
icon: const Icon(Icons.delete_outline),
|
||||
tooltip: 'Clear Data',
|
||||
onPressed: () {
|
||||
ble.clearData();
|
||||
},
|
||||
);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Consumer<BLEService>(
|
||||
builder: (context, ble, _) {
|
||||
return Column(
|
||||
children: [
|
||||
// Connection Card
|
||||
ConnectionCard(ble: ble),
|
||||
|
||||
// Statistics Card
|
||||
if (ble.isConnected) StatisticsCard(ble: ble),
|
||||
|
||||
// Data Packets List
|
||||
Expanded(
|
||||
child: ble.isConnected && ble.dataPackets.isNotEmpty
|
||||
? ListView.builder(
|
||||
controller: _scrollController,
|
||||
padding: const EdgeInsets.all(8),
|
||||
itemCount: ble.dataPackets.length,
|
||||
reverse: true, // Show newest first
|
||||
itemBuilder: (context, index) {
|
||||
final packet = ble.dataPackets[ble.dataPackets.length - 1 - index];
|
||||
return DataPacketCard(packet: packet);
|
||||
},
|
||||
)
|
||||
: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
ble.isConnected
|
||||
? Icons.bluetooth_connected
|
||||
: Icons.bluetooth_disabled,
|
||||
size: 64,
|
||||
color: Colors.grey,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
ble.isConnected
|
||||
? 'Waiting for data...'
|
||||
: 'Not connected',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
if (ble.isConnected) ...[
|
||||
const SizedBox(height: 8),
|
||||
const Text(
|
||||
'Data packets will appear here',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
floatingActionButton: Consumer<BLEService>(
|
||||
builder: (_, ble, __) {
|
||||
if (ble.isConnecting || ble.isScanning) {
|
||||
return const FloatingActionButton(
|
||||
onPressed: null,
|
||||
child: CircularProgressIndicator(color: Colors.white),
|
||||
);
|
||||
}
|
||||
|
||||
if (ble.isConnected) {
|
||||
return FloatingActionButton(
|
||||
onPressed: () async {
|
||||
await ble.disconnect();
|
||||
ble.clearData();
|
||||
},
|
||||
backgroundColor: Colors.red,
|
||||
child: const Icon(Icons.bluetooth_disabled),
|
||||
);
|
||||
}
|
||||
|
||||
return FloatingActionButton(
|
||||
onPressed: () async {
|
||||
final scaffoldMessenger = ScaffoldMessenger.of(context);
|
||||
final success = await ble.autoConnect();
|
||||
if (!success && mounted) {
|
||||
scaffoldMessenger.showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Koneksi ke timbangan gagal'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: const Icon(Icons.bluetooth_searching),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,206 +1,206 @@
|
||||
import 'dart:ui' show ImageFilter;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'devices_screen.dart';
|
||||
import 'timbang_screen.dart';
|
||||
|
||||
/// Root scaffold with bottom nav: Devices and Timbang (scale display).
|
||||
class MainShell extends StatefulWidget {
|
||||
const MainShell({super.key});
|
||||
|
||||
@override
|
||||
State<MainShell> createState() => _MainShellState();
|
||||
}
|
||||
|
||||
class _MainShellState extends State<MainShell> {
|
||||
int _index = 0;
|
||||
|
||||
static const _tabs = [
|
||||
(label: 'Devices', icon: Icons.list_alt),
|
||||
(label: 'Timbang', icon: Icons.monitor_weight),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
extendBody: true,
|
||||
body: IndexedStack(
|
||||
index: _index,
|
||||
children: const [
|
||||
DevicesScreen(),
|
||||
TimbangScreen(),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: _FloatingGlassNavigationBar(
|
||||
currentIndex: _index,
|
||||
tabs: _tabs,
|
||||
onTap: (i) => setState(() => _index = i),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _FloatingGlassNavigationBar extends StatelessWidget {
|
||||
const _FloatingGlassNavigationBar({
|
||||
required this.currentIndex,
|
||||
required this.tabs,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
final int currentIndex;
|
||||
final List<({String label, IconData icon})> tabs;
|
||||
final ValueChanged<int> onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
minimum: const EdgeInsets.fromLTRB(20, 0, 20, 18),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(32),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 24, sigmaY: 24),
|
||||
child: Container(
|
||||
height: 72,
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
Colors.white.withValues(alpha: 0.84),
|
||||
Colors.white.withValues(alpha: 0.62),
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.circular(32),
|
||||
border: Border.all(color: Colors.white.withValues(alpha: 0.9)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xFF0F172A).withValues(alpha: 0.13),
|
||||
blurRadius: 34,
|
||||
offset: const Offset(0, 18),
|
||||
),
|
||||
BoxShadow(
|
||||
color: const Color(0xFF38BDF8).withValues(alpha: 0.1),
|
||||
blurRadius: 24,
|
||||
offset: const Offset(0, -6),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
for (var i = 0; i < tabs.length; i++)
|
||||
Expanded(
|
||||
child: _GlassNavigationItem(
|
||||
icon: tabs[i].icon,
|
||||
label: tabs[i].label,
|
||||
isSelected: i == currentIndex,
|
||||
onTap: () => onTap(i),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _GlassNavigationItem extends StatelessWidget {
|
||||
const _GlassNavigationItem({
|
||||
required this.icon,
|
||||
required this.label,
|
||||
required this.isSelected,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final bool isSelected;
|
||||
final VoidCallback onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const activeColor = Color(0xFF2563EB);
|
||||
const inactiveColor = Color(0xFF64748B);
|
||||
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(26),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 220),
|
||||
curve: Curves.easeOutCubic,
|
||||
alignment: Alignment.center,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 2),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
decoration: BoxDecoration(
|
||||
gradient: isSelected
|
||||
? LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
Colors.white.withValues(alpha: 0.95),
|
||||
activeColor.withValues(alpha: 0.12),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
color: isSelected ? null : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(26),
|
||||
border: Border.all(
|
||||
color: isSelected
|
||||
? Colors.white.withValues(alpha: 0.96)
|
||||
: Colors.transparent,
|
||||
),
|
||||
boxShadow: isSelected
|
||||
? [
|
||||
BoxShadow(
|
||||
color: activeColor.withValues(alpha: 0.16),
|
||||
blurRadius: 18,
|
||||
offset: const Offset(0, 8),
|
||||
),
|
||||
]
|
||||
: null,
|
||||
),
|
||||
child: AnimatedScale(
|
||||
duration: const Duration(milliseconds: 180),
|
||||
curve: Curves.easeOutCubic,
|
||||
scale: isSelected ? 1 : 0.96,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
icon,
|
||||
color: isSelected ? activeColor : inactiveColor,
|
||||
size: 22,
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: const Duration(milliseconds: 220),
|
||||
curve: Curves.easeOutCubic,
|
||||
child: isSelected
|
||||
? Row(
|
||||
children: [
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF2563EB),
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
import 'dart:ui' show ImageFilter;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'devices_screen.dart';
|
||||
import 'timbang_screen.dart';
|
||||
|
||||
/// Root scaffold with bottom nav: Devices and Timbang (scale display).
|
||||
class MainShell extends StatefulWidget {
|
||||
const MainShell({super.key});
|
||||
|
||||
@override
|
||||
State<MainShell> createState() => _MainShellState();
|
||||
}
|
||||
|
||||
class _MainShellState extends State<MainShell> {
|
||||
int _index = 0;
|
||||
|
||||
static const _tabs = [
|
||||
(label: 'Devices', icon: Icons.list_alt),
|
||||
(label: 'Timbang', icon: Icons.monitor_weight),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
extendBody: true,
|
||||
body: IndexedStack(
|
||||
index: _index,
|
||||
children: const [
|
||||
DevicesScreen(),
|
||||
TimbangScreen(),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: _FloatingGlassNavigationBar(
|
||||
currentIndex: _index,
|
||||
tabs: _tabs,
|
||||
onTap: (i) => setState(() => _index = i),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _FloatingGlassNavigationBar extends StatelessWidget {
|
||||
const _FloatingGlassNavigationBar({
|
||||
required this.currentIndex,
|
||||
required this.tabs,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
final int currentIndex;
|
||||
final List<({String label, IconData icon})> tabs;
|
||||
final ValueChanged<int> onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
minimum: const EdgeInsets.fromLTRB(20, 0, 20, 18),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(32),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 24, sigmaY: 24),
|
||||
child: Container(
|
||||
height: 72,
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
Colors.white.withValues(alpha: 0.84),
|
||||
Colors.white.withValues(alpha: 0.62),
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.circular(32),
|
||||
border: Border.all(color: Colors.white.withValues(alpha: 0.9)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xFF0F172A).withValues(alpha: 0.13),
|
||||
blurRadius: 34,
|
||||
offset: const Offset(0, 18),
|
||||
),
|
||||
BoxShadow(
|
||||
color: const Color(0xFF38BDF8).withValues(alpha: 0.1),
|
||||
blurRadius: 24,
|
||||
offset: const Offset(0, -6),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
for (var i = 0; i < tabs.length; i++)
|
||||
Expanded(
|
||||
child: _GlassNavigationItem(
|
||||
icon: tabs[i].icon,
|
||||
label: tabs[i].label,
|
||||
isSelected: i == currentIndex,
|
||||
onTap: () => onTap(i),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _GlassNavigationItem extends StatelessWidget {
|
||||
const _GlassNavigationItem({
|
||||
required this.icon,
|
||||
required this.label,
|
||||
required this.isSelected,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final bool isSelected;
|
||||
final VoidCallback onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const activeColor = Color(0xFF2563EB);
|
||||
const inactiveColor = Color(0xFF64748B);
|
||||
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(26),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 220),
|
||||
curve: Curves.easeOutCubic,
|
||||
alignment: Alignment.center,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 2),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
decoration: BoxDecoration(
|
||||
gradient: isSelected
|
||||
? LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
Colors.white.withValues(alpha: 0.95),
|
||||
activeColor.withValues(alpha: 0.12),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
color: isSelected ? null : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(26),
|
||||
border: Border.all(
|
||||
color: isSelected
|
||||
? Colors.white.withValues(alpha: 0.96)
|
||||
: Colors.transparent,
|
||||
),
|
||||
boxShadow: isSelected
|
||||
? [
|
||||
BoxShadow(
|
||||
color: activeColor.withValues(alpha: 0.16),
|
||||
blurRadius: 18,
|
||||
offset: const Offset(0, 8),
|
||||
),
|
||||
]
|
||||
: null,
|
||||
),
|
||||
child: AnimatedScale(
|
||||
duration: const Duration(milliseconds: 180),
|
||||
curve: Curves.easeOutCubic,
|
||||
scale: isSelected ? 1 : 0.96,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
icon,
|
||||
color: isSelected ? activeColor : inactiveColor,
|
||||
size: 22,
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: const Duration(milliseconds: 220),
|
||||
curve: Curves.easeOutCubic,
|
||||
child: isSelected
|
||||
? Row(
|
||||
children: [
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF2563EB),
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
/// Central configuration for SIAB-related constants.
|
||||
///
|
||||
/// The [deviceName] can be overridden at build time using:
|
||||
/// `--dart-define=SIAB_DEVICE_NAME=YourDeviceName`.
|
||||
class SiabConfig {
|
||||
const SiabConfig._();
|
||||
|
||||
/// Logical Bluetooth name to search for when scanning SIAB devices.
|
||||
static const String deviceName = String.fromEnvironment(
|
||||
'SIAB_DEVICE_NAME',
|
||||
defaultValue: 'SIAB',
|
||||
);
|
||||
}
|
||||
|
||||
/// Central configuration for SIAB-related constants.
|
||||
///
|
||||
/// The [deviceName] can be overridden at build time using:
|
||||
/// `--dart-define=SIAB_DEVICE_NAME=YourDeviceName`.
|
||||
class SiabConfig {
|
||||
const SiabConfig._();
|
||||
|
||||
/// Logical Bluetooth name to search for when scanning SIAB devices.
|
||||
static const String deviceName = String.fromEnvironment(
|
||||
'SIAB_DEVICE_NAME',
|
||||
defaultValue: 'SIAB',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,79 +1,79 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/ble_service.dart';
|
||||
import '../siab_config.dart';
|
||||
|
||||
class ConnectionCard extends StatelessWidget {
|
||||
final BLEService ble;
|
||||
|
||||
const ConnectionCard({super.key, required this.ble});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
margin: const EdgeInsets.all(8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
ble.isConnected
|
||||
? Icons.bluetooth_connected
|
||||
: Icons.bluetooth_disabled,
|
||||
color: ble.isConnected ? Colors.green : Colors.grey,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
ble.isConnected ? 'Connected' : 'Disconnected',
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const Spacer(),
|
||||
if (ble.isScanning || ble.isConnecting)
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (ble.isConnected) ...[
|
||||
const SizedBox(height: 8),
|
||||
if (ble.deviceName != null)
|
||||
Text('Device: ${ble.deviceName}'),
|
||||
if (ble.deviceAddress != null)
|
||||
Text(
|
||||
'Address: ${ble.deviceAddress}',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
if (!ble.isConnected && !ble.isScanning && !ble.isConnecting) ...[
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: () async {
|
||||
final success = await ble.autoConnect();
|
||||
if (!success && context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Failed to find ${SiabConfig.deviceName} device',
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.search),
|
||||
label: const Text('Scan & Connect'),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/ble_service.dart';
|
||||
import '../siab_config.dart';
|
||||
|
||||
class ConnectionCard extends StatelessWidget {
|
||||
final BLEService ble;
|
||||
|
||||
const ConnectionCard({super.key, required this.ble});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
margin: const EdgeInsets.all(8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
ble.isConnected
|
||||
? Icons.bluetooth_connected
|
||||
: Icons.bluetooth_disabled,
|
||||
color: ble.isConnected ? Colors.green : Colors.grey,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
ble.isConnected ? 'Connected' : 'Disconnected',
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const Spacer(),
|
||||
if (ble.isScanning || ble.isConnecting)
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (ble.isConnected) ...[
|
||||
const SizedBox(height: 8),
|
||||
if (ble.deviceName != null)
|
||||
Text('Device: ${ble.deviceName}'),
|
||||
if (ble.deviceAddress != null)
|
||||
Text(
|
||||
'Address: ${ble.deviceAddress}',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
if (!ble.isConnected && !ble.isScanning && !ble.isConnecting) ...[
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: () async {
|
||||
final success = await ble.autoConnect();
|
||||
if (!success && context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Failed to find ${SiabConfig.deviceName} device',
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.search),
|
||||
label: const Text('Scan & Connect'),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,126 +1,126 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/ble_service.dart';
|
||||
|
||||
class DataPacketCard extends StatelessWidget {
|
||||
final DataPacket packet;
|
||||
|
||||
const DataPacketCard({super.key, required this.packet});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final timeStr = '${packet.timestamp.hour.toString().padLeft(2, '0')}:'
|
||||
'${packet.timestamp.minute.toString().padLeft(2, '0')}:'
|
||||
'${packet.timestamp.second.toString().padLeft(2, '0')}';
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: ExpansionTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
child: Text(
|
||||
'#${packet.packetNumber}',
|
||||
style: const TextStyle(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
packet.hexString,
|
||||
style: const TextStyle(fontFamily: 'monospace', fontSize: 14),
|
||||
),
|
||||
subtitle: Text('$timeStr • ${packet.data.length} bytes'),
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildSection('Hex', packet.hexString),
|
||||
const SizedBox(height: 8),
|
||||
// 'timbang' style: bytes shown in decimal (matching Python output)
|
||||
_buildSection('timbang', packet.bytesString),
|
||||
const SizedBox(height: 16),
|
||||
if (packet.value32BitUnsigned != null) ...[
|
||||
_buildValueRow(
|
||||
'32-bit Unsigned (BE)',
|
||||
packet.value32BitUnsigned.toString(),
|
||||
),
|
||||
_buildValueRow(
|
||||
'32-bit Signed (BE)',
|
||||
packet.value32BitSigned.toString(),
|
||||
),
|
||||
if (packet.value32BitUnsigned! > 0) ...[
|
||||
_buildValueRow(
|
||||
'As Float (÷100)',
|
||||
(packet.value32BitUnsigned! / 100.0).toStringAsFixed(2),
|
||||
),
|
||||
_buildValueRow(
|
||||
'As Float (÷1000)',
|
||||
(packet.value32BitUnsigned! / 1000.0).toStringAsFixed(3),
|
||||
),
|
||||
],
|
||||
],
|
||||
if (packet.value16BitUnsigned != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
_buildValueRow(
|
||||
'16-bit Unsigned (BE)',
|
||||
packet.value16BitUnsigned.toString(),
|
||||
),
|
||||
_buildValueRow(
|
||||
'16-bit Signed (BE)',
|
||||
packet.value16BitSigned.toString(),
|
||||
),
|
||||
],
|
||||
if (packet.asciiString != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
_buildSection('ASCII', packet.asciiString!),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSection(String label, String value) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
SelectableText(
|
||||
value,
|
||||
style: const TextStyle(fontFamily: 'monospace', fontSize: 14),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildValueRow(String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 12, color: Colors.grey),
|
||||
),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'monospace',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/ble_service.dart';
|
||||
|
||||
class DataPacketCard extends StatelessWidget {
|
||||
final DataPacket packet;
|
||||
|
||||
const DataPacketCard({super.key, required this.packet});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final timeStr = '${packet.timestamp.hour.toString().padLeft(2, '0')}:'
|
||||
'${packet.timestamp.minute.toString().padLeft(2, '0')}:'
|
||||
'${packet.timestamp.second.toString().padLeft(2, '0')}';
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: ExpansionTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
child: Text(
|
||||
'#${packet.packetNumber}',
|
||||
style: const TextStyle(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
packet.hexString,
|
||||
style: const TextStyle(fontFamily: 'monospace', fontSize: 14),
|
||||
),
|
||||
subtitle: Text('$timeStr • ${packet.data.length} bytes'),
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildSection('Hex', packet.hexString),
|
||||
const SizedBox(height: 8),
|
||||
// 'timbang' style: bytes shown in decimal (matching Python output)
|
||||
_buildSection('timbang', packet.bytesString),
|
||||
const SizedBox(height: 16),
|
||||
if (packet.value32BitUnsigned != null) ...[
|
||||
_buildValueRow(
|
||||
'32-bit Unsigned (BE)',
|
||||
packet.value32BitUnsigned.toString(),
|
||||
),
|
||||
_buildValueRow(
|
||||
'32-bit Signed (BE)',
|
||||
packet.value32BitSigned.toString(),
|
||||
),
|
||||
if (packet.value32BitUnsigned! > 0) ...[
|
||||
_buildValueRow(
|
||||
'As Float (÷100)',
|
||||
(packet.value32BitUnsigned! / 100.0).toStringAsFixed(2),
|
||||
),
|
||||
_buildValueRow(
|
||||
'As Float (÷1000)',
|
||||
(packet.value32BitUnsigned! / 1000.0).toStringAsFixed(3),
|
||||
),
|
||||
],
|
||||
],
|
||||
if (packet.value16BitUnsigned != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
_buildValueRow(
|
||||
'16-bit Unsigned (BE)',
|
||||
packet.value16BitUnsigned.toString(),
|
||||
),
|
||||
_buildValueRow(
|
||||
'16-bit Signed (BE)',
|
||||
packet.value16BitSigned.toString(),
|
||||
),
|
||||
],
|
||||
if (packet.asciiString != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
_buildSection('ASCII', packet.asciiString!),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSection(String label, String value) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
SelectableText(
|
||||
value,
|
||||
style: const TextStyle(fontFamily: 'monospace', fontSize: 14),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildValueRow(String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 12, color: Colors.grey),
|
||||
),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'monospace',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,76 +1,76 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/ble_service.dart';
|
||||
|
||||
class StatisticsCard extends StatelessWidget {
|
||||
final BLEService ble;
|
||||
|
||||
const StatisticsCard({super.key, required this.ble});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final duration = ble.streamingDuration;
|
||||
final durationStr = duration != null
|
||||
? '${duration.inMinutes}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}'
|
||||
: '0:00';
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_StatItem(
|
||||
icon: Icons.data_usage,
|
||||
label: 'Packets',
|
||||
value: '${ble.packetCount}',
|
||||
),
|
||||
_StatItem(
|
||||
icon: Icons.speed,
|
||||
label: 'Rate',
|
||||
value: '${ble.packetsPerSecond.toStringAsFixed(2)}/s',
|
||||
),
|
||||
_StatItem(
|
||||
icon: Icons.timer,
|
||||
label: 'Duration',
|
||||
value: durationStr,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _StatItem extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final String value;
|
||||
|
||||
const _StatItem({
|
||||
required this.icon,
|
||||
required this.label,
|
||||
required this.value,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, size: 24, color: Theme.of(context).primaryColor),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
label,
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/ble_service.dart';
|
||||
|
||||
class StatisticsCard extends StatelessWidget {
|
||||
final BLEService ble;
|
||||
|
||||
const StatisticsCard({super.key, required this.ble});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final duration = ble.streamingDuration;
|
||||
final durationStr = duration != null
|
||||
? '${duration.inMinutes}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}'
|
||||
: '0:00';
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_StatItem(
|
||||
icon: Icons.data_usage,
|
||||
label: 'Packets',
|
||||
value: '${ble.packetCount}',
|
||||
),
|
||||
_StatItem(
|
||||
icon: Icons.speed,
|
||||
label: 'Rate',
|
||||
value: '${ble.packetsPerSecond.toStringAsFixed(2)}/s',
|
||||
),
|
||||
_StatItem(
|
||||
icon: Icons.timer,
|
||||
label: 'Duration',
|
||||
value: durationStr,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _StatItem extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final String value;
|
||||
|
||||
const _StatItem({
|
||||
required this.icon,
|
||||
required this.label,
|
||||
required this.value,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, size: 24, color: Theme.of(context).primaryColor),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
label,
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
flutter/ephemeral
|
||||
flutter/ephemeral
|
||||
@@ -1,88 +1,88 @@
|
||||
# This file controls Flutter-level build steps. It should not be edited.
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
|
||||
|
||||
# Configuration provided via flutter tool.
|
||||
include(${EPHEMERAL_DIR}/generated_config.cmake)
|
||||
|
||||
# TODO: Move the rest of this into files in ephemeral. See
|
||||
# https://github.com/flutter/flutter/issues/57146.
|
||||
|
||||
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
|
||||
# which isn't available in 3.10.
|
||||
function(list_prepend LIST_NAME PREFIX)
|
||||
set(NEW_LIST "")
|
||||
foreach(element ${${LIST_NAME}})
|
||||
list(APPEND NEW_LIST "${PREFIX}${element}")
|
||||
endforeach(element)
|
||||
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# === Flutter Library ===
|
||||
# System-level dependencies.
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
|
||||
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
|
||||
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
|
||||
|
||||
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
|
||||
|
||||
# Published to parent scope for install step.
|
||||
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
|
||||
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
|
||||
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
|
||||
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
|
||||
|
||||
list(APPEND FLUTTER_LIBRARY_HEADERS
|
||||
"fl_basic_message_channel.h"
|
||||
"fl_binary_codec.h"
|
||||
"fl_binary_messenger.h"
|
||||
"fl_dart_project.h"
|
||||
"fl_engine.h"
|
||||
"fl_json_message_codec.h"
|
||||
"fl_json_method_codec.h"
|
||||
"fl_message_codec.h"
|
||||
"fl_method_call.h"
|
||||
"fl_method_channel.h"
|
||||
"fl_method_codec.h"
|
||||
"fl_method_response.h"
|
||||
"fl_plugin_registrar.h"
|
||||
"fl_plugin_registry.h"
|
||||
"fl_standard_message_codec.h"
|
||||
"fl_standard_method_codec.h"
|
||||
"fl_string_codec.h"
|
||||
"fl_value.h"
|
||||
"fl_view.h"
|
||||
"flutter_linux.h"
|
||||
)
|
||||
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
|
||||
add_library(flutter INTERFACE)
|
||||
target_include_directories(flutter INTERFACE
|
||||
"${EPHEMERAL_DIR}"
|
||||
)
|
||||
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
|
||||
target_link_libraries(flutter INTERFACE
|
||||
PkgConfig::GTK
|
||||
PkgConfig::GLIB
|
||||
PkgConfig::GIO
|
||||
)
|
||||
add_dependencies(flutter flutter_assemble)
|
||||
|
||||
# === Flutter tool backend ===
|
||||
# _phony_ is a non-existent file to force this command to run every time,
|
||||
# since currently there's no way to get a full input/output list from the
|
||||
# flutter tool.
|
||||
add_custom_command(
|
||||
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/_phony_
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
${FLUTTER_TOOL_ENVIRONMENT}
|
||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
|
||||
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(flutter_assemble DEPENDS
|
||||
"${FLUTTER_LIBRARY}"
|
||||
${FLUTTER_LIBRARY_HEADERS}
|
||||
)
|
||||
# This file controls Flutter-level build steps. It should not be edited.
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
|
||||
|
||||
# Configuration provided via flutter tool.
|
||||
include(${EPHEMERAL_DIR}/generated_config.cmake)
|
||||
|
||||
# TODO: Move the rest of this into files in ephemeral. See
|
||||
# https://github.com/flutter/flutter/issues/57146.
|
||||
|
||||
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
|
||||
# which isn't available in 3.10.
|
||||
function(list_prepend LIST_NAME PREFIX)
|
||||
set(NEW_LIST "")
|
||||
foreach(element ${${LIST_NAME}})
|
||||
list(APPEND NEW_LIST "${PREFIX}${element}")
|
||||
endforeach(element)
|
||||
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# === Flutter Library ===
|
||||
# System-level dependencies.
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
|
||||
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
|
||||
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
|
||||
|
||||
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
|
||||
|
||||
# Published to parent scope for install step.
|
||||
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
|
||||
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
|
||||
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
|
||||
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
|
||||
|
||||
list(APPEND FLUTTER_LIBRARY_HEADERS
|
||||
"fl_basic_message_channel.h"
|
||||
"fl_binary_codec.h"
|
||||
"fl_binary_messenger.h"
|
||||
"fl_dart_project.h"
|
||||
"fl_engine.h"
|
||||
"fl_json_message_codec.h"
|
||||
"fl_json_method_codec.h"
|
||||
"fl_message_codec.h"
|
||||
"fl_method_call.h"
|
||||
"fl_method_channel.h"
|
||||
"fl_method_codec.h"
|
||||
"fl_method_response.h"
|
||||
"fl_plugin_registrar.h"
|
||||
"fl_plugin_registry.h"
|
||||
"fl_standard_message_codec.h"
|
||||
"fl_standard_method_codec.h"
|
||||
"fl_string_codec.h"
|
||||
"fl_value.h"
|
||||
"fl_view.h"
|
||||
"flutter_linux.h"
|
||||
)
|
||||
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
|
||||
add_library(flutter INTERFACE)
|
||||
target_include_directories(flutter INTERFACE
|
||||
"${EPHEMERAL_DIR}"
|
||||
)
|
||||
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
|
||||
target_link_libraries(flutter INTERFACE
|
||||
PkgConfig::GTK
|
||||
PkgConfig::GLIB
|
||||
PkgConfig::GIO
|
||||
)
|
||||
add_dependencies(flutter flutter_assemble)
|
||||
|
||||
# === Flutter tool backend ===
|
||||
# _phony_ is a non-existent file to force this command to run every time,
|
||||
# since currently there's no way to get a full input/output list from the
|
||||
# flutter tool.
|
||||
add_custom_command(
|
||||
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/_phony_
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
${FLUTTER_TOOL_ENVIRONMENT}
|
||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
|
||||
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(flutter_assemble DEPENDS
|
||||
"${FLUTTER_LIBRARY}"
|
||||
${FLUTTER_LIBRARY_HEADERS}
|
||||
)
|
||||
@@ -1,26 +1,26 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(runner LANGUAGES CXX)
|
||||
|
||||
# Define the application target. To change its name, change BINARY_NAME in the
|
||||
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
|
||||
# work.
|
||||
#
|
||||
# Any new source files that you add to the application should be added here.
|
||||
add_executable(${BINARY_NAME}
|
||||
"main.cc"
|
||||
"my_application.cc"
|
||||
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
|
||||
)
|
||||
|
||||
# Apply the standard set of build settings. This can be removed for applications
|
||||
# that need different build settings.
|
||||
apply_standard_settings(${BINARY_NAME})
|
||||
|
||||
# Add preprocessor definitions for the application ID.
|
||||
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
|
||||
|
||||
# Add dependency libraries. Add any application-specific dependencies here.
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
|
||||
|
||||
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(runner LANGUAGES CXX)
|
||||
|
||||
# Define the application target. To change its name, change BINARY_NAME in the
|
||||
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
|
||||
# work.
|
||||
#
|
||||
# Any new source files that you add to the application should be added here.
|
||||
add_executable(${BINARY_NAME}
|
||||
"main.cc"
|
||||
"my_application.cc"
|
||||
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
|
||||
)
|
||||
|
||||
# Apply the standard set of build settings. This can be removed for applications
|
||||
# that need different build settings.
|
||||
apply_standard_settings(${BINARY_NAME})
|
||||
|
||||
# Add preprocessor definitions for the application ID.
|
||||
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
|
||||
|
||||
# Add dependency libraries. Add any application-specific dependencies here.
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
|
||||
|
||||
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "my_application.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
g_autoptr(MyApplication) app = my_application_new();
|
||||
return g_application_run(G_APPLICATION(app), argc, argv);
|
||||
}
|
||||
#include "my_application.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
g_autoptr(MyApplication) app = my_application_new();
|
||||
return g_application_run(G_APPLICATION(app), argc, argv);
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
#ifndef FLUTTER_MY_APPLICATION_H_
|
||||
#define FLUTTER_MY_APPLICATION_H_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
|
||||
GtkApplication)
|
||||
|
||||
/**
|
||||
* my_application_new:
|
||||
*
|
||||
* Creates a new Flutter-based application.
|
||||
*
|
||||
* Returns: a new #MyApplication.
|
||||
*/
|
||||
MyApplication* my_application_new();
|
||||
|
||||
#endif // FLUTTER_MY_APPLICATION_H_
|
||||
#ifndef FLUTTER_MY_APPLICATION_H_
|
||||
#define FLUTTER_MY_APPLICATION_H_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
|
||||
GtkApplication)
|
||||
|
||||
/**
|
||||
* my_application_new:
|
||||
*
|
||||
* Creates a new Flutter-based application.
|
||||
*
|
||||
* Returns: a new #MyApplication.
|
||||
*/
|
||||
MyApplication* my_application_new();
|
||||
|
||||
#endif // FLUTTER_MY_APPLICATION_H_
|
||||
@@ -1,7 +1,7 @@
|
||||
# Flutter-related
|
||||
**/Flutter/ephemeral/
|
||||
**/Pods/
|
||||
|
||||
# Xcode-related
|
||||
**/dgph
|
||||
**/xcuserdata/
|
||||
# Flutter-related
|
||||
**/Flutter/ephemeral/
|
||||
**/Pods/
|
||||
|
||||
# Xcode-related
|
||||
**/dgph
|
||||
**/xcuserdata/
|
||||
@@ -1 +1 @@
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
@@ -1 +1 @@
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,99 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||
BuildableName = "siab_bluetooth_app.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||
BuildableName = "siab_bluetooth_app.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "331C80D4294CF70F00263BE5"
|
||||
BuildableName = "RunnerTests.xctest"
|
||||
BlueprintName = "RunnerTests"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
enableGPUValidationMode = "1"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||
BuildableName = "siab_bluetooth_app.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||
BuildableName = "siab_bluetooth_app.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||
BuildableName = "siab_bluetooth_app.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||
BuildableName = "siab_bluetooth_app.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "331C80D4294CF70F00263BE5"
|
||||
BuildableName = "RunnerTests.xctest"
|
||||
BlueprintName = "RunnerTests"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
enableGPUValidationMode = "1"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||
BuildableName = "siab_bluetooth_app.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||
BuildableName = "siab_bluetooth_app.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,13 +1,13 @@
|
||||
import Cocoa
|
||||
import FlutterMacOS
|
||||
|
||||
@main
|
||||
class AppDelegate: FlutterAppDelegate {
|
||||
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
import Cocoa
|
||||
import FlutterMacOS
|
||||
|
||||
@main
|
||||
class AppDelegate: FlutterAppDelegate {
|
||||
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,68 +1,68 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_16.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_32.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_32.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_64.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_128.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_256.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_256.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_512.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_512.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_1024.png",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_16.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_32.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_32.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_64.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_128.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_256.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_256.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_512.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_512.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_1024.png",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||