init
							
								
								
									
										25
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					node_modules
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Output
 | 
				
			||||||
 | 
					.output
 | 
				
			||||||
 | 
					.vercel
 | 
				
			||||||
 | 
					.netlify
 | 
				
			||||||
 | 
					.wrangler
 | 
				
			||||||
 | 
					/.svelte-kit
 | 
				
			||||||
 | 
					/build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# OS
 | 
				
			||||||
 | 
					.DS_Store
 | 
				
			||||||
 | 
					Thumbs.db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Env
 | 
				
			||||||
 | 
					.env
 | 
				
			||||||
 | 
					.env.*
 | 
				
			||||||
 | 
					!.env.example
 | 
				
			||||||
 | 
					!.env.test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Vite
 | 
				
			||||||
 | 
					vite.config.js.timestamp-*
 | 
				
			||||||
 | 
					vite.config.ts.timestamp-*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/.direnv
 | 
				
			||||||
							
								
								
									
										4
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					# Package Managers
 | 
				
			||||||
 | 
					package-lock.json
 | 
				
			||||||
 | 
					pnpm-lock.yaml
 | 
				
			||||||
 | 
					yarn.lock
 | 
				
			||||||
							
								
								
									
										15
									
								
								.prettierrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
						"useTabs": true,
 | 
				
			||||||
 | 
						"singleQuote": true,
 | 
				
			||||||
 | 
						"trailingComma": "none",
 | 
				
			||||||
 | 
						"printWidth": 100,
 | 
				
			||||||
 | 
						"plugins": ["prettier-plugin-svelte"],
 | 
				
			||||||
 | 
						"overrides": [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"files": "*.svelte",
 | 
				
			||||||
 | 
								"options": {
 | 
				
			||||||
 | 
									"parser": "svelte"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					# sv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Creating a project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you're seeing this, you've probably already done this step. Congrats!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					# create a new project in the current directory
 | 
				
			||||||
 | 
					npx sv create
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# create a new project in my-app
 | 
				
			||||||
 | 
					npx sv create my-app
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Developing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					npm run dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# or start the server and open the app in a new browser tab
 | 
				
			||||||
 | 
					npm run dev -- --open
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Building
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To create a production version of your app:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					npm run build
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can preview the production build with `npm run preview`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
 | 
				
			||||||
							
								
								
									
										101
									
								
								android/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,101 @@
 | 
				
			|||||||
 | 
					# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Built application files
 | 
				
			||||||
 | 
					*.apk
 | 
				
			||||||
 | 
					*.aar
 | 
				
			||||||
 | 
					*.ap_
 | 
				
			||||||
 | 
					*.aab
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Files for the ART/Dalvik VM
 | 
				
			||||||
 | 
					*.dex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Java class files
 | 
				
			||||||
 | 
					*.class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Generated files
 | 
				
			||||||
 | 
					bin/
 | 
				
			||||||
 | 
					gen/
 | 
				
			||||||
 | 
					out/
 | 
				
			||||||
 | 
					#  Uncomment the following line in case you need and you don't have the release build type files in your app
 | 
				
			||||||
 | 
					# release/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Gradle files
 | 
				
			||||||
 | 
					.gradle/
 | 
				
			||||||
 | 
					build/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Local configuration file (sdk path, etc)
 | 
				
			||||||
 | 
					local.properties
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Proguard folder generated by Eclipse
 | 
				
			||||||
 | 
					proguard/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Log Files
 | 
				
			||||||
 | 
					*.log
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Android Studio Navigation editor temp files
 | 
				
			||||||
 | 
					.navigation/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Android Studio captures folder
 | 
				
			||||||
 | 
					captures/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# IntelliJ
 | 
				
			||||||
 | 
					*.iml
 | 
				
			||||||
 | 
					.idea/workspace.xml
 | 
				
			||||||
 | 
					.idea/tasks.xml
 | 
				
			||||||
 | 
					.idea/gradle.xml
 | 
				
			||||||
 | 
					.idea/assetWizardSettings.xml
 | 
				
			||||||
 | 
					.idea/dictionaries
 | 
				
			||||||
 | 
					.idea/libraries
 | 
				
			||||||
 | 
					# Android Studio 3 in .gitignore file.
 | 
				
			||||||
 | 
					.idea/caches
 | 
				
			||||||
 | 
					.idea/modules.xml
 | 
				
			||||||
 | 
					# Comment next line if keeping position of elements in Navigation Editor is relevant for you
 | 
				
			||||||
 | 
					.idea/navEditor.xml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Keystore files
 | 
				
			||||||
 | 
					# Uncomment the following lines if you do not want to check your keystore files in.
 | 
				
			||||||
 | 
					#*.jks
 | 
				
			||||||
 | 
					#*.keystore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# External native build folder generated in Android Studio 2.2 and later
 | 
				
			||||||
 | 
					.externalNativeBuild
 | 
				
			||||||
 | 
					.cxx/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Google Services (e.g. APIs or Firebase)
 | 
				
			||||||
 | 
					# google-services.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Freeline
 | 
				
			||||||
 | 
					freeline.py
 | 
				
			||||||
 | 
					freeline/
 | 
				
			||||||
 | 
					freeline_project_description.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# fastlane
 | 
				
			||||||
 | 
					fastlane/report.xml
 | 
				
			||||||
 | 
					fastlane/Preview.html
 | 
				
			||||||
 | 
					fastlane/screenshots
 | 
				
			||||||
 | 
					fastlane/test_output
 | 
				
			||||||
 | 
					fastlane/readme.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Version control
 | 
				
			||||||
 | 
					vcs.xml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# lint
 | 
				
			||||||
 | 
					lint/intermediates/
 | 
				
			||||||
 | 
					lint/generated/
 | 
				
			||||||
 | 
					lint/outputs/
 | 
				
			||||||
 | 
					lint/tmp/
 | 
				
			||||||
 | 
					# lint/reports/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Android Profiling
 | 
				
			||||||
 | 
					*.hprof
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Cordova plugins for Capacitor
 | 
				
			||||||
 | 
					capacitor-cordova-android-plugins
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Copied web assets
 | 
				
			||||||
 | 
					app/src/main/assets/public
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Generated Config files
 | 
				
			||||||
 | 
					app/src/main/assets/capacitor.config.json
 | 
				
			||||||
 | 
					app/src/main/assets/capacitor.plugins.json
 | 
				
			||||||
 | 
					app/src/main/res/xml/config.xml
 | 
				
			||||||
							
								
								
									
										3
									
								
								android/.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# Default ignored files
 | 
				
			||||||
 | 
					/shelf/
 | 
				
			||||||
 | 
					/workspace.xml
 | 
				
			||||||
							
								
								
									
										6
									
								
								android/.idea/compiler.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="CompilerConfiguration">
 | 
				
			||||||
 | 
					    <bytecodeTargetLevel target="21" />
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
							
								
								
									
										10
									
								
								android/.idea/deploymentTargetSelector.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="deploymentTargetSelector">
 | 
				
			||||||
 | 
					    <selectionStates>
 | 
				
			||||||
 | 
					      <SelectionState runConfigName="app">
 | 
				
			||||||
 | 
					        <option name="selectionMode" value="DROPDOWN" />
 | 
				
			||||||
 | 
					      </SelectionState>
 | 
				
			||||||
 | 
					    </selectionStates>
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
							
								
								
									
										6
									
								
								android/.idea/kotlinc.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="KotlinJpsPluginSettings">
 | 
				
			||||||
 | 
					    <option name="version" value="1.9.25" />
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
							
								
								
									
										10
									
								
								android/.idea/migrations.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="ProjectMigrations">
 | 
				
			||||||
 | 
					    <option name="MigrateToGradleLocalJavaHome">
 | 
				
			||||||
 | 
					      <set>
 | 
				
			||||||
 | 
					        <option value="$PROJECT_DIR$" />
 | 
				
			||||||
 | 
					      </set>
 | 
				
			||||||
 | 
					    </option>
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
							
								
								
									
										9
									
								
								android/.idea/misc.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="ExternalStorageConfigurationManager" enabled="true" />
 | 
				
			||||||
 | 
					  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
 | 
				
			||||||
 | 
					    <output url="file://$PROJECT_DIR$/build/classes" />
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					  <component name="ProjectType">
 | 
				
			||||||
 | 
					    <option name="id" value="Android" />
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
							
								
								
									
										17
									
								
								android/.idea/runConfigurations.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="RunConfigurationProducerService">
 | 
				
			||||||
 | 
					    <option name="ignoredProducers">
 | 
				
			||||||
 | 
					      <set>
 | 
				
			||||||
 | 
					        <option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
 | 
				
			||||||
 | 
					        <option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
 | 
				
			||||||
 | 
					        <option value="com.intellij.execution.junit.PatternConfigurationProducer" />
 | 
				
			||||||
 | 
					        <option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
 | 
				
			||||||
 | 
					        <option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
 | 
				
			||||||
 | 
					        <option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
 | 
				
			||||||
 | 
					        <option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
 | 
				
			||||||
 | 
					        <option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
 | 
				
			||||||
 | 
					      </set>
 | 
				
			||||||
 | 
					    </option>
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
							
								
								
									
										2
									
								
								android/app/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					/build/*
 | 
				
			||||||
 | 
					!/build/.npmkeep
 | 
				
			||||||
							
								
								
									
										54
									
								
								android/app/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					apply plugin: 'com.android.application'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					android {
 | 
				
			||||||
 | 
					    namespace "com.example.app"
 | 
				
			||||||
 | 
					    compileSdk rootProject.ext.compileSdkVersion
 | 
				
			||||||
 | 
					    defaultConfig {
 | 
				
			||||||
 | 
					        applicationId "com.example.app"
 | 
				
			||||||
 | 
					        minSdkVersion rootProject.ext.minSdkVersion
 | 
				
			||||||
 | 
					        targetSdkVersion rootProject.ext.targetSdkVersion
 | 
				
			||||||
 | 
					        versionCode 1
 | 
				
			||||||
 | 
					        versionName "1.0"
 | 
				
			||||||
 | 
					        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 | 
				
			||||||
 | 
					        aaptOptions {
 | 
				
			||||||
 | 
					             // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
 | 
				
			||||||
 | 
					             // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
 | 
				
			||||||
 | 
					            ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    buildTypes {
 | 
				
			||||||
 | 
					        release {
 | 
				
			||||||
 | 
					            minifyEnabled false
 | 
				
			||||||
 | 
					            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					repositories {
 | 
				
			||||||
 | 
					    flatDir{
 | 
				
			||||||
 | 
					        dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dependencies {
 | 
				
			||||||
 | 
					    implementation fileTree(include: ['*.jar'], dir: 'libs')
 | 
				
			||||||
 | 
					    implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
 | 
				
			||||||
 | 
					    implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
 | 
				
			||||||
 | 
					    implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
 | 
				
			||||||
 | 
					    implementation project(':capacitor-android')
 | 
				
			||||||
 | 
					    testImplementation "junit:junit:$junitVersion"
 | 
				
			||||||
 | 
					    androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
 | 
				
			||||||
 | 
					    androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
 | 
				
			||||||
 | 
					    implementation project(':capacitor-cordova-android-plugins')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					apply from: 'capacitor.build.gradle'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try {
 | 
				
			||||||
 | 
					    def servicesJSON = file('google-services.json')
 | 
				
			||||||
 | 
					    if (servicesJSON.text) {
 | 
				
			||||||
 | 
					        apply plugin: 'com.google.gms.google-services'
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} catch(Exception e) {
 | 
				
			||||||
 | 
					    logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								android/app/capacitor.build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					android {
 | 
				
			||||||
 | 
					  compileOptions {
 | 
				
			||||||
 | 
					      sourceCompatibility JavaVersion.VERSION_21
 | 
				
			||||||
 | 
					      targetCompatibility JavaVersion.VERSION_21
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
 | 
				
			||||||
 | 
					dependencies {
 | 
				
			||||||
 | 
					    implementation project(':capacitor-community-safe-area')
 | 
				
			||||||
 | 
					    implementation project(':capacitor-filesystem')
 | 
				
			||||||
 | 
					    implementation project(':capacitor-haptics')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (hasProperty('postBuildExtras')) {
 | 
				
			||||||
 | 
					  postBuildExtras()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								android/app/proguard-rules.pro
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					# Add project specific ProGuard rules here.
 | 
				
			||||||
 | 
					# You can control the set of applied configuration files using the
 | 
				
			||||||
 | 
					# proguardFiles setting in build.gradle.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# For more details, see
 | 
				
			||||||
 | 
					#   http://developer.android.com/guide/developing/tools/proguard.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# If your project uses WebView with JS, uncomment the following
 | 
				
			||||||
 | 
					# and specify the fully qualified class name to the JavaScript interface
 | 
				
			||||||
 | 
					# class:
 | 
				
			||||||
 | 
					#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
 | 
				
			||||||
 | 
					#   public *;
 | 
				
			||||||
 | 
					#}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Uncomment this to preserve the line number information for
 | 
				
			||||||
 | 
					# debugging stack traces.
 | 
				
			||||||
 | 
					#-keepattributes SourceFile,LineNumberTable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# If you keep the line number information, uncomment this to
 | 
				
			||||||
 | 
					# hide the original source file name.
 | 
				
			||||||
 | 
					#-renamesourcefileattribute SourceFile
 | 
				
			||||||
@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					package com.getcapacitor.myapp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.junit.Assert.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.content.Context;
 | 
				
			||||||
 | 
					import androidx.test.ext.junit.runners.AndroidJUnit4;
 | 
				
			||||||
 | 
					import androidx.test.platform.app.InstrumentationRegistry;
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					import org.junit.runner.RunWith;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Instrumented test, which will execute on an Android device.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@RunWith(AndroidJUnit4.class)
 | 
				
			||||||
 | 
					public class ExampleInstrumentedTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void useAppContext() throws Exception {
 | 
				
			||||||
 | 
					        // Context of the app under test.
 | 
				
			||||||
 | 
					        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertEquals("com.getcapacitor.app", appContext.getPackageName());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										40
									
								
								android/app/src/main/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <application
 | 
				
			||||||
 | 
					        android:allowBackup="true"
 | 
				
			||||||
 | 
					        android:icon="@mipmap/ic_launcher"
 | 
				
			||||||
 | 
					        android:label="@string/app_name"
 | 
				
			||||||
 | 
					        android:roundIcon="@mipmap/ic_launcher_round"
 | 
				
			||||||
 | 
					        android:supportsRtl="true"
 | 
				
			||||||
 | 
					        android:theme="@style/AppTheme">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <activity
 | 
				
			||||||
 | 
					            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode|navigation"
 | 
				
			||||||
 | 
					            android:name=".MainActivity"
 | 
				
			||||||
 | 
					            android:label="@string/title_activity_main"
 | 
				
			||||||
 | 
					            android:theme="@style/AppTheme.NoActionBarLaunch"
 | 
				
			||||||
 | 
					            android:launchMode="singleTask"
 | 
				
			||||||
 | 
					            android:exported="true">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <intent-filter>
 | 
				
			||||||
 | 
					                <action android:name="android.intent.action.MAIN" />
 | 
				
			||||||
 | 
					                <category android:name="android.intent.category.LAUNCHER" />
 | 
				
			||||||
 | 
					            </intent-filter>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </activity>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <provider
 | 
				
			||||||
 | 
					            android:name="androidx.core.content.FileProvider"
 | 
				
			||||||
 | 
					            android:authorities="${applicationId}.fileprovider"
 | 
				
			||||||
 | 
					            android:exported="false"
 | 
				
			||||||
 | 
					            android:grantUriPermissions="true">
 | 
				
			||||||
 | 
					            <meta-data
 | 
				
			||||||
 | 
					                android:name="android.support.FILE_PROVIDER_PATHS"
 | 
				
			||||||
 | 
					                android:resource="@xml/file_paths"></meta-data>
 | 
				
			||||||
 | 
					        </provider>
 | 
				
			||||||
 | 
					    </application>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- Permissions -->
 | 
				
			||||||
 | 
					    <uses-permission android:name="android.permission.INTERNET" />
 | 
				
			||||||
 | 
					</manifest>
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/ic_launcher-playstore.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 82 KiB  | 
@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					package com.example.app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.getcapacitor.BridgeActivity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class MainActivity extends BridgeActivity {}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-land-hdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-land-mdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-land-xhdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-land-xxhdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 14 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-land-xxxhdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 17 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-port-hdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-port-mdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-port-xhdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-port-xxhdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 13 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-port-xxxhdpi/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 17 KiB  | 
@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    xmlns:aapt="http://schemas.android.com/aapt"
 | 
				
			||||||
 | 
					    android:width="108dp"
 | 
				
			||||||
 | 
					    android:height="108dp"
 | 
				
			||||||
 | 
					    android:viewportHeight="108"
 | 
				
			||||||
 | 
					    android:viewportWidth="108">
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					        android:fillType="evenOdd"
 | 
				
			||||||
 | 
					        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
 | 
				
			||||||
 | 
					        android:strokeColor="#00000000"
 | 
				
			||||||
 | 
					        android:strokeWidth="1">
 | 
				
			||||||
 | 
					        <aapt:attr name="android:fillColor">
 | 
				
			||||||
 | 
					            <gradient
 | 
				
			||||||
 | 
					                android:endX="78.5885"
 | 
				
			||||||
 | 
					                android:endY="90.9159"
 | 
				
			||||||
 | 
					                android:startX="48.7653"
 | 
				
			||||||
 | 
					                android:startY="61.0927"
 | 
				
			||||||
 | 
					                android:type="linear">
 | 
				
			||||||
 | 
					                <item
 | 
				
			||||||
 | 
					                    android:color="#44000000"
 | 
				
			||||||
 | 
					                    android:offset="0.0" />
 | 
				
			||||||
 | 
					                <item
 | 
				
			||||||
 | 
					                    android:color="#00000000"
 | 
				
			||||||
 | 
					                    android:offset="1.0" />
 | 
				
			||||||
 | 
					            </gradient>
 | 
				
			||||||
 | 
					        </aapt:attr>
 | 
				
			||||||
 | 
					    </path>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					        android:fillColor="#FFFFFF"
 | 
				
			||||||
 | 
					        android:fillType="nonZero"
 | 
				
			||||||
 | 
					        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
 | 
				
			||||||
 | 
					        android:strokeColor="#00000000"
 | 
				
			||||||
 | 
					        android:strokeWidth="1" />
 | 
				
			||||||
 | 
					</vector>
 | 
				
			||||||
							
								
								
									
										74
									
								
								android/app/src/main/res/drawable/ic_launcher_background.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<vector
 | 
				
			||||||
 | 
					    android:height="108dp"
 | 
				
			||||||
 | 
					    android:width="108dp"
 | 
				
			||||||
 | 
					    android:viewportHeight="108"
 | 
				
			||||||
 | 
					    android:viewportWidth="108"
 | 
				
			||||||
 | 
					    xmlns:android="http://schemas.android.com/apk/res/android">
 | 
				
			||||||
 | 
					    <path android:fillColor="#3DDC84"
 | 
				
			||||||
 | 
					          android:pathData="M0,0h108v108h-108z"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M9,0L9,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M19,0L19,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M29,0L29,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M39,0L39,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M49,0L49,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M59,0L59,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M69,0L69,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M79,0L79,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M89,0L89,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M99,0L99,108"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,9L108,9"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,19L108,19"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,29L108,29"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,39L108,39"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,49L108,49"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,59L108,59"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,69L108,69"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,79L108,79"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,89L108,89"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M0,99L108,99"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M19,29L89,29"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M19,39L89,39"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M19,49L89,49"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M19,59L89,59"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M19,69L89,69"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M19,79L89,79"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M29,19L29,89"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M39,19L39,89"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M49,19L49,89"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M59,19L59,89"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M69,19L69,89"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					    <path android:fillColor="#00000000" android:pathData="M79,19L79,89"
 | 
				
			||||||
 | 
					          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 | 
				
			||||||
 | 
					</vector>
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable/splash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										12
									
								
								android/app/src/main/res/layout/activity_main.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
				
			||||||
 | 
					    xmlns:tools="http://schemas.android.com/tools"
 | 
				
			||||||
 | 
					    android:layout_width="match_parent"
 | 
				
			||||||
 | 
					    android:layout_height="match_parent"
 | 
				
			||||||
 | 
					    tools:context=".MainActivity">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <WebView
 | 
				
			||||||
 | 
					        android:layout_width="match_parent"
 | 
				
			||||||
 | 
					        android:layout_height="match_parent" />
 | 
				
			||||||
 | 
					</androidx.coordinatorlayout.widget.CoordinatorLayout>
 | 
				
			||||||
@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
 | 
				
			||||||
 | 
					    <background android:drawable="@color/ic_launcher_background"/>
 | 
				
			||||||
 | 
					    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
 | 
				
			||||||
 | 
					</adaptive-icon>
 | 
				
			||||||
@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
 | 
				
			||||||
 | 
					    <background android:drawable="@color/ic_launcher_background"/>
 | 
				
			||||||
 | 
					    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
 | 
				
			||||||
 | 
					</adaptive-icon>
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-hdpi/ic_launcher.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-mdpi/ic_launcher.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.9 KiB  | 
| 
		 After Width: | Height: | Size: 5.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.0 KiB  | 
| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.0 KiB  | 
| 
		 After Width: | Height: | Size: 17 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 15 KiB  | 
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<resources>
 | 
				
			||||||
 | 
					    <color name="ic_launcher_background">#00274C</color>
 | 
				
			||||||
 | 
					</resources>
 | 
				
			||||||
							
								
								
									
										7
									
								
								android/app/src/main/res/values/strings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					<?xml version='1.0' encoding='utf-8'?>
 | 
				
			||||||
 | 
					<resources>
 | 
				
			||||||
 | 
					    <string name="app_name">umich-scanner</string>
 | 
				
			||||||
 | 
					    <string name="title_activity_main">umich-scanner</string>
 | 
				
			||||||
 | 
					    <string name="package_name">com.example.app</string>
 | 
				
			||||||
 | 
					    <string name="custom_url_scheme">com.example.app</string>
 | 
				
			||||||
 | 
					</resources>
 | 
				
			||||||
							
								
								
									
										22
									
								
								android/app/src/main/res/values/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<resources>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- Base application theme. -->
 | 
				
			||||||
 | 
					    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
 | 
				
			||||||
 | 
					        <!-- Customize your theme here. -->
 | 
				
			||||||
 | 
					        <item name="colorPrimary">@color/colorPrimary</item>
 | 
				
			||||||
 | 
					        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
 | 
				
			||||||
 | 
					        <item name="colorAccent">@color/colorAccent</item>
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
 | 
				
			||||||
 | 
					        <item name="windowActionBar">false</item>
 | 
				
			||||||
 | 
					        <item name="windowNoTitle">true</item>
 | 
				
			||||||
 | 
					        <item name="android:background">@null</item>
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
 | 
				
			||||||
 | 
					        <item name="android:background">@drawable/splash</item>
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</resources>
 | 
				
			||||||
							
								
								
									
										5
									
								
								android/app/src/main/res/xml/file_paths.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<paths xmlns:android="http://schemas.android.com/apk/res/android">
 | 
				
			||||||
 | 
					    <external-path name="my_images" path="." />
 | 
				
			||||||
 | 
					    <cache-path name="my_cache_images" path="." />
 | 
				
			||||||
 | 
					</paths>
 | 
				
			||||||
@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					package com.getcapacitor.myapp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.junit.Assert.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Example local unit test, which will execute on the development machine (host).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class ExampleUnitTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void addition_isCorrect() throws Exception {
 | 
				
			||||||
 | 
					        assertEquals(4, 2 + 2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								android/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					// Top-level build file where you can add configuration options common to all sub-projects/modules.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					buildscript {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    repositories {
 | 
				
			||||||
 | 
					        google()
 | 
				
			||||||
 | 
					        mavenCentral()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    dependencies {
 | 
				
			||||||
 | 
					        classpath 'com.android.tools.build:gradle:8.7.2'
 | 
				
			||||||
 | 
					        classpath 'com.google.gms:google-services:4.4.2'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // NOTE: Do not place your application dependencies here; they belong
 | 
				
			||||||
 | 
					        // in the individual module build.gradle files
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					apply from: "variables.gradle"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					allprojects {
 | 
				
			||||||
 | 
					    repositories {
 | 
				
			||||||
 | 
					        google()
 | 
				
			||||||
 | 
					        mavenCentral()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					task clean(type: Delete) {
 | 
				
			||||||
 | 
					    delete rootProject.buildDir
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								android/capacitor.settings.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
 | 
				
			||||||
 | 
					include ':capacitor-android'
 | 
				
			||||||
 | 
					project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include ':capacitor-community-safe-area'
 | 
				
			||||||
 | 
					project(':capacitor-community-safe-area').projectDir = new File('../node_modules/@capacitor-community/safe-area/android')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include ':capacitor-filesystem'
 | 
				
			||||||
 | 
					project(':capacitor-filesystem').projectDir = new File('../node_modules/@capacitor/filesystem/android')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include ':capacitor-haptics'
 | 
				
			||||||
 | 
					project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/haptics/android')
 | 
				
			||||||
							
								
								
									
										22
									
								
								android/gradle.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					# Project-wide Gradle settings.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# IDE (e.g. Android Studio) users:
 | 
				
			||||||
 | 
					# Gradle settings configured through the IDE *will override*
 | 
				
			||||||
 | 
					# any settings specified in this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# For more details on how to configure your build environment visit
 | 
				
			||||||
 | 
					# http://www.gradle.org/docs/current/userguide/build_environment.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Specifies the JVM arguments used for the daemon process.
 | 
				
			||||||
 | 
					# The setting is particularly useful for tweaking memory settings.
 | 
				
			||||||
 | 
					org.gradle.jvmargs=-Xmx1536m
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# When configured, Gradle will run in incubating parallel mode.
 | 
				
			||||||
 | 
					# This option should only be used with decoupled projects. More details, visit
 | 
				
			||||||
 | 
					# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
 | 
				
			||||||
 | 
					# org.gradle.parallel=true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# AndroidX package structure to make it clearer which packages are bundled with the
 | 
				
			||||||
 | 
					# Android operating system, and which are packaged with your app's APK
 | 
				
			||||||
 | 
					# https://developer.android.com/topic/libraries/support-library/androidx-rn
 | 
				
			||||||
 | 
					android.useAndroidX=true
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								android/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										7
									
								
								android/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					distributionBase=GRADLE_USER_HOME
 | 
				
			||||||
 | 
					distributionPath=wrapper/dists
 | 
				
			||||||
 | 
					distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
 | 
				
			||||||
 | 
					networkTimeout=10000
 | 
				
			||||||
 | 
					validateDistributionUrl=true
 | 
				
			||||||
 | 
					zipStoreBase=GRADLE_USER_HOME
 | 
				
			||||||
 | 
					zipStorePath=wrapper/dists
 | 
				
			||||||
							
								
								
									
										252
									
								
								android/gradlew
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						@@ -0,0 +1,252 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright © 2015-2021 the original authors.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#      https://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# SPDX-License-Identifier: Apache-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##############################################################################
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   Gradle start up script for POSIX generated by Gradle.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   Important for running:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
 | 
				
			||||||
 | 
					#       noncompliant, but you have some other compliant shell such as ksh or
 | 
				
			||||||
 | 
					#       bash, then to run this script, type that shell name before the whole
 | 
				
			||||||
 | 
					#       command line, like:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#           ksh Gradle
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#       Busybox and similar reduced shells will NOT work, because this script
 | 
				
			||||||
 | 
					#       requires all of these POSIX shell features:
 | 
				
			||||||
 | 
					#         * functions;
 | 
				
			||||||
 | 
					#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
 | 
				
			||||||
 | 
					#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
 | 
				
			||||||
 | 
					#         * compound commands having a testable exit status, especially «case»;
 | 
				
			||||||
 | 
					#         * various built-in commands including «command», «set», and «ulimit».
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   Important for patching:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   (2) This script targets any POSIX shell, so it avoids extensions provided
 | 
				
			||||||
 | 
					#       by Bash, Ksh, etc; in particular arrays are avoided.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#       The "traditional" practice of packing multiple parameters into a
 | 
				
			||||||
 | 
					#       space-separated string is a well documented source of bugs and security
 | 
				
			||||||
 | 
					#       problems, so this is (mostly) avoided, by progressively accumulating
 | 
				
			||||||
 | 
					#       options in "$@", and eventually passing that to Java.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
 | 
				
			||||||
 | 
					#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
 | 
				
			||||||
 | 
					#       see the in-line comments for details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#       There are tweaks for specific operating systems such as AIX, CygWin,
 | 
				
			||||||
 | 
					#       Darwin, MinGW, and NonStop.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   (3) This script is generated from the Groovy template
 | 
				
			||||||
 | 
					#       https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
 | 
				
			||||||
 | 
					#       within the Gradle project.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#       You can find Gradle at https://github.com/gradle/gradle/.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					##############################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Attempt to set APP_HOME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Resolve links: $0 may be a link
 | 
				
			||||||
 | 
					app_path=$0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Need this for daisy-chained symlinks.
 | 
				
			||||||
 | 
					while
 | 
				
			||||||
 | 
					    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
 | 
				
			||||||
 | 
					    [ -h "$app_path" ]
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
					    ls=$( ls -ld "$app_path" )
 | 
				
			||||||
 | 
					    link=${ls#*' -> '}
 | 
				
			||||||
 | 
					    case $link in             #(
 | 
				
			||||||
 | 
					      /*)   app_path=$link ;; #(
 | 
				
			||||||
 | 
					      *)    app_path=$APP_HOME$link ;;
 | 
				
			||||||
 | 
					    esac
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This is normally unused
 | 
				
			||||||
 | 
					# shellcheck disable=SC2034
 | 
				
			||||||
 | 
					APP_BASE_NAME=${0##*/}
 | 
				
			||||||
 | 
					# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
 | 
				
			||||||
 | 
					APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
 | 
				
			||||||
 | 
					' "$PWD" ) || exit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Use the maximum available, or set MAX_FD != -1 to use that value.
 | 
				
			||||||
 | 
					MAX_FD=maximum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					warn () {
 | 
				
			||||||
 | 
					    echo "$*"
 | 
				
			||||||
 | 
					} >&2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					die () {
 | 
				
			||||||
 | 
					    echo
 | 
				
			||||||
 | 
					    echo "$*"
 | 
				
			||||||
 | 
					    echo
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					} >&2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# OS specific support (must be 'true' or 'false').
 | 
				
			||||||
 | 
					cygwin=false
 | 
				
			||||||
 | 
					msys=false
 | 
				
			||||||
 | 
					darwin=false
 | 
				
			||||||
 | 
					nonstop=false
 | 
				
			||||||
 | 
					case "$( uname )" in                #(
 | 
				
			||||||
 | 
					  CYGWIN* )         cygwin=true  ;; #(
 | 
				
			||||||
 | 
					  Darwin* )         darwin=true  ;; #(
 | 
				
			||||||
 | 
					  MSYS* | MINGW* )  msys=true    ;; #(
 | 
				
			||||||
 | 
					  NONSTOP* )        nonstop=true ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Determine the Java command to use to start the JVM.
 | 
				
			||||||
 | 
					if [ -n "$JAVA_HOME" ] ; then
 | 
				
			||||||
 | 
					    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
 | 
				
			||||||
 | 
					        # IBM's JDK on AIX uses strange locations for the executables
 | 
				
			||||||
 | 
					        JAVACMD=$JAVA_HOME/jre/sh/java
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        JAVACMD=$JAVA_HOME/bin/java
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    if [ ! -x "$JAVACMD" ] ; then
 | 
				
			||||||
 | 
					        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please set the JAVA_HOME variable in your environment to match the
 | 
				
			||||||
 | 
					location of your Java installation."
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					    JAVACMD=java
 | 
				
			||||||
 | 
					    if ! command -v java >/dev/null 2>&1
 | 
				
			||||||
 | 
					    then
 | 
				
			||||||
 | 
					        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please set the JAVA_HOME variable in your environment to match the
 | 
				
			||||||
 | 
					location of your Java installation."
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Increase the maximum file descriptors if we can.
 | 
				
			||||||
 | 
					if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
 | 
				
			||||||
 | 
					    case $MAX_FD in #(
 | 
				
			||||||
 | 
					      max*)
 | 
				
			||||||
 | 
					        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
 | 
				
			||||||
 | 
					        # shellcheck disable=SC2039,SC3045
 | 
				
			||||||
 | 
					        MAX_FD=$( ulimit -H -n ) ||
 | 
				
			||||||
 | 
					            warn "Could not query maximum file descriptor limit"
 | 
				
			||||||
 | 
					    esac
 | 
				
			||||||
 | 
					    case $MAX_FD in  #(
 | 
				
			||||||
 | 
					      '' | soft) :;; #(
 | 
				
			||||||
 | 
					      *)
 | 
				
			||||||
 | 
					        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
 | 
				
			||||||
 | 
					        # shellcheck disable=SC2039,SC3045
 | 
				
			||||||
 | 
					        ulimit -n "$MAX_FD" ||
 | 
				
			||||||
 | 
					            warn "Could not set maximum file descriptor limit to $MAX_FD"
 | 
				
			||||||
 | 
					    esac
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Collect all arguments for the java command, stacking in reverse order:
 | 
				
			||||||
 | 
					#   * args from the command line
 | 
				
			||||||
 | 
					#   * the main class name
 | 
				
			||||||
 | 
					#   * -classpath
 | 
				
			||||||
 | 
					#   * -D...appname settings
 | 
				
			||||||
 | 
					#   * --module-path (only if needed)
 | 
				
			||||||
 | 
					#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# For Cygwin or MSYS, switch paths to Windows format before running java
 | 
				
			||||||
 | 
					if "$cygwin" || "$msys" ; then
 | 
				
			||||||
 | 
					    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
 | 
				
			||||||
 | 
					    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    JAVACMD=$( cygpath --unix "$JAVACMD" )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Now convert the arguments - kludge to limit ourselves to /bin/sh
 | 
				
			||||||
 | 
					    for arg do
 | 
				
			||||||
 | 
					        if
 | 
				
			||||||
 | 
					            case $arg in                                #(
 | 
				
			||||||
 | 
					              -*)   false ;;                            # don't mess with options #(
 | 
				
			||||||
 | 
					              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
 | 
				
			||||||
 | 
					                    [ -e "$t" ] ;;                      #(
 | 
				
			||||||
 | 
					              *)    false ;;
 | 
				
			||||||
 | 
					            esac
 | 
				
			||||||
 | 
					        then
 | 
				
			||||||
 | 
					            arg=$( cygpath --path --ignore --mixed "$arg" )
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        # Roll the args list around exactly as many times as the number of
 | 
				
			||||||
 | 
					        # args, so each arg winds up back in the position where it started, but
 | 
				
			||||||
 | 
					        # possibly modified.
 | 
				
			||||||
 | 
					        #
 | 
				
			||||||
 | 
					        # NB: a `for` loop captures its iteration list before it begins, so
 | 
				
			||||||
 | 
					        # changing the positional parameters here affects neither the number of
 | 
				
			||||||
 | 
					        # iterations, nor the values presented in `arg`.
 | 
				
			||||||
 | 
					        shift                   # remove old arg
 | 
				
			||||||
 | 
					        set -- "$@" "$arg"      # push replacement arg
 | 
				
			||||||
 | 
					    done
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 | 
				
			||||||
 | 
					DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Collect all arguments for the java command:
 | 
				
			||||||
 | 
					#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
 | 
				
			||||||
 | 
					#     and any embedded shellness will be escaped.
 | 
				
			||||||
 | 
					#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
 | 
				
			||||||
 | 
					#     treated as '${Hostname}' itself on the command line.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set -- \
 | 
				
			||||||
 | 
					        "-Dorg.gradle.appname=$APP_BASE_NAME" \
 | 
				
			||||||
 | 
					        -classpath "$CLASSPATH" \
 | 
				
			||||||
 | 
					        org.gradle.wrapper.GradleWrapperMain \
 | 
				
			||||||
 | 
					        "$@"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Stop when "xargs" is not available.
 | 
				
			||||||
 | 
					if ! command -v xargs >/dev/null 2>&1
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
					    die "xargs is not available"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Use "xargs" to parse quoted args.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# In Bash we could simply go:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
 | 
				
			||||||
 | 
					#   set -- "${ARGS[@]}" "$@"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# but POSIX shell has neither arrays nor command substitution, so instead we
 | 
				
			||||||
 | 
					# post-process each arg (as a line of input to sed) to backslash-escape any
 | 
				
			||||||
 | 
					# character that might be a shell metacharacter, then use eval to reverse
 | 
				
			||||||
 | 
					# that process (while maintaining the separation between arguments), and wrap
 | 
				
			||||||
 | 
					# the whole thing up as a single "set" statement.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This will of course break if any of these variables contains a newline or
 | 
				
			||||||
 | 
					# an unmatched quote.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eval "set -- $(
 | 
				
			||||||
 | 
					        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
 | 
				
			||||||
 | 
					        xargs -n1 |
 | 
				
			||||||
 | 
					        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
 | 
				
			||||||
 | 
					        tr '\n' ' '
 | 
				
			||||||
 | 
					    )" '"$@"'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exec "$JAVACMD" "$@"
 | 
				
			||||||
							
								
								
									
										94
									
								
								android/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					@rem
 | 
				
			||||||
 | 
					@rem Copyright 2015 the original author or authors.
 | 
				
			||||||
 | 
					@rem
 | 
				
			||||||
 | 
					@rem Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					@rem you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					@rem You may obtain a copy of the License at
 | 
				
			||||||
 | 
					@rem
 | 
				
			||||||
 | 
					@rem      https://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					@rem
 | 
				
			||||||
 | 
					@rem Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					@rem distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					@rem See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					@rem limitations under the License.
 | 
				
			||||||
 | 
					@rem
 | 
				
			||||||
 | 
					@rem SPDX-License-Identifier: Apache-2.0
 | 
				
			||||||
 | 
					@rem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@if "%DEBUG%"=="" @echo off
 | 
				
			||||||
 | 
					@rem ##########################################################################
 | 
				
			||||||
 | 
					@rem
 | 
				
			||||||
 | 
					@rem  Gradle startup script for Windows
 | 
				
			||||||
 | 
					@rem
 | 
				
			||||||
 | 
					@rem ##########################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@rem Set local scope for the variables with windows NT shell
 | 
				
			||||||
 | 
					if "%OS%"=="Windows_NT" setlocal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set DIRNAME=%~dp0
 | 
				
			||||||
 | 
					if "%DIRNAME%"=="" set DIRNAME=.
 | 
				
			||||||
 | 
					@rem This is normally unused
 | 
				
			||||||
 | 
					set APP_BASE_NAME=%~n0
 | 
				
			||||||
 | 
					set APP_HOME=%DIRNAME%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@rem Resolve any "." and ".." in APP_HOME to make it shorter.
 | 
				
			||||||
 | 
					for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 | 
				
			||||||
 | 
					set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@rem Find java.exe
 | 
				
			||||||
 | 
					if defined JAVA_HOME goto findJavaFromJavaHome
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set JAVA_EXE=java.exe
 | 
				
			||||||
 | 
					%JAVA_EXE% -version >NUL 2>&1
 | 
				
			||||||
 | 
					if %ERRORLEVEL% equ 0 goto execute
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo. 1>&2
 | 
				
			||||||
 | 
					echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
 | 
				
			||||||
 | 
					echo. 1>&2
 | 
				
			||||||
 | 
					echo Please set the JAVA_HOME variable in your environment to match the 1>&2
 | 
				
			||||||
 | 
					echo location of your Java installation. 1>&2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					goto fail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:findJavaFromJavaHome
 | 
				
			||||||
 | 
					set JAVA_HOME=%JAVA_HOME:"=%
 | 
				
			||||||
 | 
					set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if exist "%JAVA_EXE%" goto execute
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo. 1>&2
 | 
				
			||||||
 | 
					echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
 | 
				
			||||||
 | 
					echo. 1>&2
 | 
				
			||||||
 | 
					echo Please set the JAVA_HOME variable in your environment to match the 1>&2
 | 
				
			||||||
 | 
					echo location of your Java installation. 1>&2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					goto fail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:execute
 | 
				
			||||||
 | 
					@rem Setup the command line
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@rem Execute Gradle
 | 
				
			||||||
 | 
					"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:end
 | 
				
			||||||
 | 
					@rem End local scope for the variables with windows NT shell
 | 
				
			||||||
 | 
					if %ERRORLEVEL% equ 0 goto mainEnd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:fail
 | 
				
			||||||
 | 
					rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
 | 
				
			||||||
 | 
					rem the _cmd.exe /c_ return code!
 | 
				
			||||||
 | 
					set EXIT_CODE=%ERRORLEVEL%
 | 
				
			||||||
 | 
					if %EXIT_CODE% equ 0 set EXIT_CODE=1
 | 
				
			||||||
 | 
					if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
 | 
				
			||||||
 | 
					exit /b %EXIT_CODE%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:mainEnd
 | 
				
			||||||
 | 
					if "%OS%"=="Windows_NT" endlocal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:omega
 | 
				
			||||||
							
								
								
									
										5
									
								
								android/settings.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					include ':app'
 | 
				
			||||||
 | 
					include ':capacitor-cordova-android-plugins'
 | 
				
			||||||
 | 
					project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					apply from: 'capacitor.settings.gradle'
 | 
				
			||||||
							
								
								
									
										16
									
								
								android/variables.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					ext {
 | 
				
			||||||
 | 
					    minSdkVersion = 23
 | 
				
			||||||
 | 
					    compileSdkVersion = 35
 | 
				
			||||||
 | 
					    targetSdkVersion = 35
 | 
				
			||||||
 | 
					    androidxActivityVersion = '1.9.2'
 | 
				
			||||||
 | 
					    androidxAppCompatVersion = '1.7.0'
 | 
				
			||||||
 | 
					    androidxCoordinatorLayoutVersion = '1.2.0'
 | 
				
			||||||
 | 
					    androidxCoreVersion = '1.15.0'
 | 
				
			||||||
 | 
					    androidxFragmentVersion = '1.8.4'
 | 
				
			||||||
 | 
					    coreSplashScreenVersion = '1.0.1'
 | 
				
			||||||
 | 
					    androidxWebkitVersion = '1.12.1'
 | 
				
			||||||
 | 
					    junitVersion = '4.13.2'
 | 
				
			||||||
 | 
					    androidxJunitVersion = '1.2.1'
 | 
				
			||||||
 | 
					    androidxEspressoCoreVersion = '3.6.1'
 | 
				
			||||||
 | 
					    cordovaAndroidVersion = '10.1.1'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								capacitor.config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					import type { CapacitorConfig } from '@capacitor/cli';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const config: CapacitorConfig = {
 | 
				
			||||||
 | 
					  appId: 'com.example.app',
 | 
				
			||||||
 | 
					  appName: 'umich-scanner',
 | 
				
			||||||
 | 
					  webDir: 'build',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default config;
 | 
				
			||||||
							
								
								
									
										34
									
								
								eslint.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					import prettier from 'eslint-config-prettier';
 | 
				
			||||||
 | 
					import js from '@eslint/js';
 | 
				
			||||||
 | 
					import { includeIgnoreFile } from '@eslint/compat';
 | 
				
			||||||
 | 
					import svelte from 'eslint-plugin-svelte';
 | 
				
			||||||
 | 
					import globals from 'globals';
 | 
				
			||||||
 | 
					import { fileURLToPath } from 'node:url';
 | 
				
			||||||
 | 
					import ts from 'typescript-eslint';
 | 
				
			||||||
 | 
					const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ts.config(
 | 
				
			||||||
 | 
						includeIgnoreFile(gitignorePath),
 | 
				
			||||||
 | 
						js.configs.recommended,
 | 
				
			||||||
 | 
						...ts.configs.recommended,
 | 
				
			||||||
 | 
						...svelte.configs['flat/recommended'],
 | 
				
			||||||
 | 
						prettier,
 | 
				
			||||||
 | 
						...svelte.configs['flat/prettier'],
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							languageOptions: {
 | 
				
			||||||
 | 
								globals: {
 | 
				
			||||||
 | 
									...globals.browser,
 | 
				
			||||||
 | 
									...globals.node
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							files: ['**/*.svelte'],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							languageOptions: {
 | 
				
			||||||
 | 
								parserOptions: {
 | 
				
			||||||
 | 
									parser: ts.parser
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
							
								
								
									
										25
									
								
								flake.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "nodes": {
 | 
				
			||||||
 | 
					    "nixpkgs": {
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1739736696,
 | 
				
			||||||
 | 
					        "narHash": "sha256-zON2GNBkzsIyALlOCFiEBcIjI4w38GYOb+P+R4S8Jsw=",
 | 
				
			||||||
 | 
					        "rev": "d74a2335ac9c133d6bbec9fc98d91a77f1604c1f",
 | 
				
			||||||
 | 
					        "revCount": 754461,
 | 
				
			||||||
 | 
					        "type": "tarball",
 | 
				
			||||||
 | 
					        "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.754461%2Brev-d74a2335ac9c133d6bbec9fc98d91a77f1604c1f/01951426-5a87-7b75-8413-1a0d9ec5ff04/source.tar.gz?rev=d74a2335ac9c133d6bbec9fc98d91a77f1604c1f&revCount=754461"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "type": "tarball",
 | 
				
			||||||
 | 
					        "url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.%2A.tar.gz"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "root": {
 | 
				
			||||||
 | 
					      "inputs": {
 | 
				
			||||||
 | 
					        "nixpkgs": "nixpkgs"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "root": "root",
 | 
				
			||||||
 | 
					  "version": 7
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								flake.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  description = "A Nix-flake-based Node.js development environment";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  outputs = { self, nixpkgs }:
 | 
				
			||||||
 | 
					    let
 | 
				
			||||||
 | 
					      supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
 | 
				
			||||||
 | 
					      forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
 | 
				
			||||||
 | 
					        pkgs = import nixpkgs { inherit system; overlays = [ self.overlays.default ]; };
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    in
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      overlays.default = final: prev: rec {
 | 
				
			||||||
 | 
					        nodejs = prev.nodejs;
 | 
				
			||||||
 | 
					        yarn = (prev.yarn.override { inherit nodejs; });
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      devShells = forEachSupportedSystem ({ pkgs }: {
 | 
				
			||||||
 | 
					        default = pkgs.mkShell {
 | 
				
			||||||
 | 
					          packages = with pkgs; [ node2nix nodejs nodePackages.pnpm yarn ];
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										5272
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										52
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
						"name": "umich-scanner",
 | 
				
			||||||
 | 
						"private": true,
 | 
				
			||||||
 | 
						"version": "0.0.1",
 | 
				
			||||||
 | 
						"type": "module",
 | 
				
			||||||
 | 
						"scripts": {
 | 
				
			||||||
 | 
							"dev": "vite dev",
 | 
				
			||||||
 | 
							"build": "vite build && npx cap sync",
 | 
				
			||||||
 | 
							"preview": "vite preview",
 | 
				
			||||||
 | 
							"prepare": "svelte-kit sync || echo ''",
 | 
				
			||||||
 | 
							"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
 | 
				
			||||||
 | 
							"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
 | 
				
			||||||
 | 
							"format": "prettier --write .",
 | 
				
			||||||
 | 
							"lint": "prettier --check . && eslint ."
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						"devDependencies": {
 | 
				
			||||||
 | 
							"@capacitor/cli": "^7.0.1",
 | 
				
			||||||
 | 
							"@eslint/compat": "^1.2.5",
 | 
				
			||||||
 | 
							"@eslint/js": "^9.18.0",
 | 
				
			||||||
 | 
							"@sveltejs/adapter-static": "^3.0.8",
 | 
				
			||||||
 | 
							"@sveltejs/kit": "^2.16.0",
 | 
				
			||||||
 | 
							"@sveltejs/vite-plugin-svelte": "^5.0.0",
 | 
				
			||||||
 | 
							"bits-ui": "^1.3.0",
 | 
				
			||||||
 | 
							"eslint": "^9.18.0",
 | 
				
			||||||
 | 
							"eslint-config-prettier": "^10.0.1",
 | 
				
			||||||
 | 
							"eslint-plugin-svelte": "^2.46.1",
 | 
				
			||||||
 | 
							"globals": "^15.14.0",
 | 
				
			||||||
 | 
							"prettier": "^3.4.2",
 | 
				
			||||||
 | 
							"prettier-plugin-svelte": "^3.3.3",
 | 
				
			||||||
 | 
							"svelte": "^5.0.0",
 | 
				
			||||||
 | 
							"svelte-check": "^4.0.0",
 | 
				
			||||||
 | 
							"typescript": "^5.0.0",
 | 
				
			||||||
 | 
							"typescript-eslint": "^8.20.0",
 | 
				
			||||||
 | 
							"vite": "^6.0.0"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						"dependencies": {
 | 
				
			||||||
 | 
							"@capacitor-community/safe-area": "^7.0.0-alpha.1",
 | 
				
			||||||
 | 
							"@capacitor/android": "^7.0.1",
 | 
				
			||||||
 | 
							"@capacitor/core": "^7.0.1",
 | 
				
			||||||
 | 
							"@capacitor/filesystem": "^7.0.0",
 | 
				
			||||||
 | 
							"@capacitor/haptics": "^7.0.0",
 | 
				
			||||||
 | 
							"@tailwindcss/vite": "^4.0.6",
 | 
				
			||||||
 | 
							"clsx": "^2.1.1",
 | 
				
			||||||
 | 
							"lucide-svelte": "^0.475.0",
 | 
				
			||||||
 | 
							"mode-watcher": "^0.5.1",
 | 
				
			||||||
 | 
							"svelte-sonner": "^0.3.28",
 | 
				
			||||||
 | 
							"tailwind-merge": "^3.0.1",
 | 
				
			||||||
 | 
							"tailwind-variants": "^0.3.1",
 | 
				
			||||||
 | 
							"tailwindcss": "^4.0.6",
 | 
				
			||||||
 | 
							"tailwindcss-animate": "^1.0.7"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										179
									
								
								src/app.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,179 @@
 | 
				
			|||||||
 | 
					@import "tailwindcss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@plugin 'tailwindcss-animate';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@custom-variant dark (&:where(.dark, .dark *));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@theme {
 | 
				
			||||||
 | 
					  --color-background: hsl(var(--background));
 | 
				
			||||||
 | 
					  --color-foreground: hsl(var(--foreground));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-card: hsl(var(--card));
 | 
				
			||||||
 | 
					  --color-card-foreground: hsl(var(--card-foreground));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-popover: hsl(var(--popover));
 | 
				
			||||||
 | 
					  --color-popover-foreground: hsl(var(--popover-foreground));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-primary: hsl(var(--primary));
 | 
				
			||||||
 | 
					  --color-primary-foreground: hsl(var(--primary-foreground));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-secondary: hsl(var(--secondary));
 | 
				
			||||||
 | 
					  --color-secondary-foreground: hsl(var(--secondary-foreground));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-muted: hsl(var(--muted));
 | 
				
			||||||
 | 
					  --color-muted-foreground: hsl(var(--muted-foreground));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-accent: hsl(var(--accent));
 | 
				
			||||||
 | 
					  --color-accent-foreground: hsl(var(--accent-foreground));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-destructive: hsl(var(--destructive));
 | 
				
			||||||
 | 
					  --color-destructive-foreground: hsl(var(--destructive-foreground));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-border: hsl(var(--border));
 | 
				
			||||||
 | 
					  --color-input: hsl(var(--input));
 | 
				
			||||||
 | 
					  --color-ring: hsl(var(--ring));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-chart-1: hsl(var(--chart-1));
 | 
				
			||||||
 | 
					  --color-chart-2: hsl(var(--chart-2));
 | 
				
			||||||
 | 
					  --color-chart-3: hsl(var(--chart-3));
 | 
				
			||||||
 | 
					  --color-chart-4: hsl(var(--chart-4));
 | 
				
			||||||
 | 
					  --color-chart-5: hsl(var(--chart-5));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --color-sidebar: hsl(var(--sidebar-background));
 | 
				
			||||||
 | 
					  --color-sidebar-foreground: hsl(var(--sidebar-foreground));
 | 
				
			||||||
 | 
					  --color-sidebar-primary: hsl(var(--sidebar-primary));
 | 
				
			||||||
 | 
					  --color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
 | 
				
			||||||
 | 
					  --color-sidebar-accent: hsl(var(--sidebar-accent));
 | 
				
			||||||
 | 
					  --color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
 | 
				
			||||||
 | 
					  --color-sidebar-border: hsl(var(--sidebar-border));
 | 
				
			||||||
 | 
					  --color-sidebar-ring: hsl(var(--sidebar-ring));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --radius-lg: var(--radius);
 | 
				
			||||||
 | 
					  --radius-md: calc(var(--radius) - 2px);
 | 
				
			||||||
 | 
					  --radius-sm: calc(var(--radius) - 4px);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --animate-accordion-down: accordion-down 0.2s ease-out;
 | 
				
			||||||
 | 
					  --animate-accordion-up: accordion-up 0.2s ease-out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @keyframes accordion-down {
 | 
				
			||||||
 | 
					    from {
 | 
				
			||||||
 | 
					      height: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    to {
 | 
				
			||||||
 | 
					      height: var(--radix-accordion-content-height);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @keyframes accordion-up {
 | 
				
			||||||
 | 
					    from {
 | 
				
			||||||
 | 
					      height: var(--radix-accordion-content-height);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    to {
 | 
				
			||||||
 | 
					      height: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					  The default border color has changed to `currentColor` in Tailwind CSS v4,
 | 
				
			||||||
 | 
					  so we've added these compatibility styles to make sure everything still
 | 
				
			||||||
 | 
					  looks the same as it did with Tailwind CSS v3.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  If we ever want to remove these styles, we need to add an explicit border
 | 
				
			||||||
 | 
					  color utility to any element that depends on these defaults.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					@layer base {
 | 
				
			||||||
 | 
					  *,
 | 
				
			||||||
 | 
					  ::after,
 | 
				
			||||||
 | 
					  ::before,
 | 
				
			||||||
 | 
					  ::backdrop,
 | 
				
			||||||
 | 
					  ::file-selector-button {
 | 
				
			||||||
 | 
					    border-color: var(--color-gray-200, currentColor);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@layer utilities {
 | 
				
			||||||
 | 
					  body {
 | 
				
			||||||
 | 
					    font-family: Arial, Helvetica, sans-serif;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@layer base {
 | 
				
			||||||
 | 
					  :root {
 | 
				
			||||||
 | 
					    --background: 0 0% 100%;
 | 
				
			||||||
 | 
					    --foreground: 240 10% 3.9%;
 | 
				
			||||||
 | 
					    --card: 0 0% 100%;
 | 
				
			||||||
 | 
					    --card-foreground: 240 10% 3.9%;
 | 
				
			||||||
 | 
					    --popover: 0 0% 100%;
 | 
				
			||||||
 | 
					    --popover-foreground: 240 10% 3.9%;
 | 
				
			||||||
 | 
					    --primary: 240 5.9% 10%;
 | 
				
			||||||
 | 
					    --primary-foreground: 0 0% 98%;
 | 
				
			||||||
 | 
					    --secondary: 240 4.8% 95.9%;
 | 
				
			||||||
 | 
					    --secondary-foreground: 240 5.9% 10%;
 | 
				
			||||||
 | 
					    --muted: 240 4.8% 95.9%;
 | 
				
			||||||
 | 
					    --muted-foreground: 240 3.8% 46.1%;
 | 
				
			||||||
 | 
					    --accent: 240 4.8% 95.9%;
 | 
				
			||||||
 | 
					    --accent-foreground: 240 5.9% 10%;
 | 
				
			||||||
 | 
					    --destructive: 0 84.2% 60.2%;
 | 
				
			||||||
 | 
					    --destructive-foreground: 0 0% 98%;
 | 
				
			||||||
 | 
					    --border: 240 5.9% 90%;
 | 
				
			||||||
 | 
					    --input: 240 5.9% 90%;
 | 
				
			||||||
 | 
					    --ring: 240 10% 3.9%;
 | 
				
			||||||
 | 
					    --chart-1: 12 76% 61%;
 | 
				
			||||||
 | 
					    --chart-2: 173 58% 39%;
 | 
				
			||||||
 | 
					    --chart-3: 197 37% 24%;
 | 
				
			||||||
 | 
					    --chart-4: 43 74% 66%;
 | 
				
			||||||
 | 
					    --chart-5: 27 87% 67%;
 | 
				
			||||||
 | 
					    --radius: 0.5rem;
 | 
				
			||||||
 | 
					    --sidebar-background: 0 0% 98%;
 | 
				
			||||||
 | 
					    --sidebar-foreground: 240 5.3% 26.1%;
 | 
				
			||||||
 | 
					    --sidebar-primary: 240 5.9% 10%;
 | 
				
			||||||
 | 
					    --sidebar-primary-foreground: 0 0% 98%;
 | 
				
			||||||
 | 
					    --sidebar-accent: 240 4.8% 95.9%;
 | 
				
			||||||
 | 
					    --sidebar-accent-foreground: 240 5.9% 10%;
 | 
				
			||||||
 | 
					    --sidebar-border: 220 13% 91%;
 | 
				
			||||||
 | 
					    --sidebar-ring: 217.2 91.2% 59.8%;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  .dark {
 | 
				
			||||||
 | 
					    --background: 240 10% 3.9%;
 | 
				
			||||||
 | 
					    --foreground: 0 0% 98%;
 | 
				
			||||||
 | 
					    --card: 240 10% 3.9%;
 | 
				
			||||||
 | 
					    --card-foreground: 0 0% 98%;
 | 
				
			||||||
 | 
					    --popover: 240 10% 3.9%;
 | 
				
			||||||
 | 
					    --popover-foreground: 0 0% 98%;
 | 
				
			||||||
 | 
					    --primary: 0 0% 98%;
 | 
				
			||||||
 | 
					    --primary-foreground: 240 5.9% 10%;
 | 
				
			||||||
 | 
					    --secondary: 240 3.7% 15.9%;
 | 
				
			||||||
 | 
					    --secondary-foreground: 0 0% 98%;
 | 
				
			||||||
 | 
					    --muted: 240 3.7% 15.9%;
 | 
				
			||||||
 | 
					    --muted-foreground: 240 5% 64.9%;
 | 
				
			||||||
 | 
					    --accent: 240 3.7% 15.9%;
 | 
				
			||||||
 | 
					    --accent-foreground: 0 0% 98%;
 | 
				
			||||||
 | 
					    --destructive: 0 62.8% 30.6%;
 | 
				
			||||||
 | 
					    --destructive-foreground: 0 0% 98%;
 | 
				
			||||||
 | 
					    --border: 240 3.7% 15.9%;
 | 
				
			||||||
 | 
					    --input: 240 3.7% 15.9%;
 | 
				
			||||||
 | 
					    --ring: 240 4.9% 83.9%;
 | 
				
			||||||
 | 
					    --chart-1: 220 70% 50%;
 | 
				
			||||||
 | 
					    --chart-2: 160 60% 45%;
 | 
				
			||||||
 | 
					    --chart-3: 30 80% 55%;
 | 
				
			||||||
 | 
					    --chart-4: 280 65% 60%;
 | 
				
			||||||
 | 
					    --chart-5: 340 75% 55%;
 | 
				
			||||||
 | 
					    --sidebar-background: 240 5.9% 10%;
 | 
				
			||||||
 | 
					    --sidebar-foreground: 240 4.8% 95.9%;
 | 
				
			||||||
 | 
					    --sidebar-primary: 224.3 76.3% 48%;
 | 
				
			||||||
 | 
					    --sidebar-primary-foreground: 0 0% 100%;
 | 
				
			||||||
 | 
					    --sidebar-accent: 240 3.7% 15.9%;
 | 
				
			||||||
 | 
					    --sidebar-accent-foreground: 240 4.8% 95.9%;
 | 
				
			||||||
 | 
					    --sidebar-border: 240 3.7% 15.9%;
 | 
				
			||||||
 | 
					    --sidebar-ring: 217.2 91.2% 59.8%;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@layer base {
 | 
				
			||||||
 | 
					  * {
 | 
				
			||||||
 | 
					    @apply border-border;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  body {
 | 
				
			||||||
 | 
					    @apply bg-background text-foreground;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/app.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					// See https://svelte.dev/docs/kit/types#app.d.ts
 | 
				
			||||||
 | 
					// for information about these interfaces
 | 
				
			||||||
 | 
					declare global {
 | 
				
			||||||
 | 
						namespace App {
 | 
				
			||||||
 | 
							// interface Error {}
 | 
				
			||||||
 | 
							// interface Locals {}
 | 
				
			||||||
 | 
							// interface PageData {}
 | 
				
			||||||
 | 
							// interface PageState {}
 | 
				
			||||||
 | 
							// interface Platform {}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {};
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/app.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					<!doctype html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
						<head>
 | 
				
			||||||
 | 
							<meta charset="utf-8" />
 | 
				
			||||||
 | 
							<link rel="icon" href="%sveltekit.assets%/favicon.png" />
 | 
				
			||||||
 | 
							<meta name="viewport" content="initial-scale=1, viewport-fit=cover" />
 | 
				
			||||||
 | 
							%sveltekit.head%
 | 
				
			||||||
 | 
						</head>
 | 
				
			||||||
 | 
						<body data-sveltekit-preload-data="hover">
 | 
				
			||||||
 | 
							<div style="display: contents">%sveltekit.body%</div>
 | 
				
			||||||
 | 
						</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/hooks.client.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					import type { ClientInit } from '@sveltejs/kit';
 | 
				
			||||||
 | 
					import { SafeArea } from '@capacitor-community/safe-area';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const init: ClientInit = async () => {
 | 
				
			||||||
 | 
					    await SafeArea.enable({
 | 
				
			||||||
 | 
					        config: {
 | 
				
			||||||
 | 
					            customColorsForSystemBars: true,
 | 
				
			||||||
 | 
					            statusBarColor: '#00000000', // transparent
 | 
				
			||||||
 | 
					            statusBarContent: 'light',
 | 
				
			||||||
 | 
					            navigationBarColor: '#00000000', // transparent
 | 
				
			||||||
 | 
					            navigationBarContent: 'light',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										76
									
								
								src/lib/ScanCapture.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					    import { Haptics, ImpactStyle } from '@capacitor/haptics';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							focused = $bindable(false),
 | 
				
			||||||
 | 
							scanning = $bindable(false),
 | 
				
			||||||
 | 
							onscan
 | 
				
			||||||
 | 
						}: {
 | 
				
			||||||
 | 
							focused?: boolean;
 | 
				
			||||||
 | 
							scanning?: boolean;
 | 
				
			||||||
 | 
							onscan: (value: string) => void;
 | 
				
			||||||
 | 
						} = $props();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data for manual inputs
 | 
				
			||||||
 | 
						let inputElement: HTMLInputElement | null = null;
 | 
				
			||||||
 | 
						let unfocusTimeout: NodeJS.Timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						async function onKeydown(event: KeyboardEvent) {
 | 
				
			||||||
 | 
							// If we this is a manual input
 | 
				
			||||||
 | 
							if (focused) {
 | 
				
			||||||
 | 
								// Auto unfocus after 5 seconds of inactivity
 | 
				
			||||||
 | 
								clearTimeout(unfocusTimeout);
 | 
				
			||||||
 | 
								unfocusTimeout = setTimeout(() => {
 | 
				
			||||||
 | 
									inputElement?.blur();
 | 
				
			||||||
 | 
								}, 10000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Check if this is an indicator that scanning has been initiated
 | 
				
			||||||
 | 
							if (event.key == 'Unidentified') {
 | 
				
			||||||
 | 
								scanning = true;
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Send the key to onscan
 | 
				
			||||||
 | 
							if ((event.key == 'Tab' || event.key == 'Enter' || event.key == 'Backspace' || event.key == "Home" || event.key == "Delete")) {
 | 
				
			||||||
 | 
								// Prevent tab or enter from doing anything
 | 
				
			||||||
 | 
								event.preventDefault();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Send key as text
 | 
				
			||||||
 | 
								onscan(event.key);
 | 
				
			||||||
 | 
							} else if (event.key.length == 1) {
 | 
				
			||||||
 | 
								onscan(event.key);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Haptics.impact({ style: ImpactStyle.Light });
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						async function onKeyup(event: KeyboardEvent) {
 | 
				
			||||||
 | 
							if (event.key == 'Unidentified' && scanning) {
 | 
				
			||||||
 | 
								scanning = false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function focusIn(e: any) {
 | 
				
			||||||
 | 
							if (e.target?.nodeName == 'INPUT') {
 | 
				
			||||||
 | 
								focused = true;
 | 
				
			||||||
 | 
								inputElement = e.target;
 | 
				
			||||||
 | 
					            Haptics.selectionStart();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function focusOut() {
 | 
				
			||||||
 | 
							focused = false;
 | 
				
			||||||
 | 
							inputElement = null;
 | 
				
			||||||
 | 
					        Haptics.selectionEnd();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<svelte:window
 | 
				
			||||||
 | 
						on:keydown={onKeydown}
 | 
				
			||||||
 | 
						on:keyup={onKeyup}
 | 
				
			||||||
 | 
						on:focusin={focusIn}
 | 
				
			||||||
 | 
						on:focusout={focusOut}
 | 
				
			||||||
 | 
					/>
 | 
				
			||||||
							
								
								
									
										74
									
								
								src/lib/components/ui/button/button.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					<script lang="ts" module>
 | 
				
			||||||
 | 
						import type { WithElementRef } from "bits-ui";
 | 
				
			||||||
 | 
						import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
 | 
				
			||||||
 | 
						import { type VariantProps, tv } from "tailwind-variants";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export const buttonVariants = tv({
 | 
				
			||||||
 | 
							base: "ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
 | 
				
			||||||
 | 
							variants: {
 | 
				
			||||||
 | 
								variant: {
 | 
				
			||||||
 | 
									default: "bg-primary text-primary-foreground hover:bg-primary/90",
 | 
				
			||||||
 | 
									destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
 | 
				
			||||||
 | 
									outline:
 | 
				
			||||||
 | 
										"border-input bg-background hover:bg-accent hover:text-accent-foreground border",
 | 
				
			||||||
 | 
									secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
 | 
				
			||||||
 | 
									ghost: "hover:bg-accent hover:text-accent-foreground",
 | 
				
			||||||
 | 
									link: "text-primary underline-offset-4 hover:underline",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								size: {
 | 
				
			||||||
 | 
									default: "h-10 px-4 py-2",
 | 
				
			||||||
 | 
									sm: "h-9 rounded-md px-3",
 | 
				
			||||||
 | 
									lg: "h-11 rounded-md px-8",
 | 
				
			||||||
 | 
									icon: "h-10 w-10",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							defaultVariants: {
 | 
				
			||||||
 | 
								variant: "default",
 | 
				
			||||||
 | 
								size: "default",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
 | 
				
			||||||
 | 
						export type ButtonSize = VariantProps<typeof buttonVariants>["size"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
 | 
				
			||||||
 | 
							WithElementRef<HTMLAnchorAttributes> & {
 | 
				
			||||||
 | 
								variant?: ButtonVariant;
 | 
				
			||||||
 | 
								size?: ButtonSize;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import { cn } from "$lib/utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							class: className,
 | 
				
			||||||
 | 
							variant = "default",
 | 
				
			||||||
 | 
							size = "default",
 | 
				
			||||||
 | 
							ref = $bindable(null),
 | 
				
			||||||
 | 
							href = undefined,
 | 
				
			||||||
 | 
							type = "button",
 | 
				
			||||||
 | 
							children,
 | 
				
			||||||
 | 
							...restProps
 | 
				
			||||||
 | 
						}: ButtonProps = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{#if href}
 | 
				
			||||||
 | 
						<a
 | 
				
			||||||
 | 
							bind:this={ref}
 | 
				
			||||||
 | 
							class={cn(buttonVariants({ variant, size }), className)}
 | 
				
			||||||
 | 
							{href}
 | 
				
			||||||
 | 
							{...restProps}
 | 
				
			||||||
 | 
						>
 | 
				
			||||||
 | 
							{@render children?.()}
 | 
				
			||||||
 | 
						</a>
 | 
				
			||||||
 | 
					{:else}
 | 
				
			||||||
 | 
						<button
 | 
				
			||||||
 | 
							bind:this={ref}
 | 
				
			||||||
 | 
							class={cn(buttonVariants({ variant, size }), className)}
 | 
				
			||||||
 | 
							{type}
 | 
				
			||||||
 | 
							{...restProps}
 | 
				
			||||||
 | 
						>
 | 
				
			||||||
 | 
							{@render children?.()}
 | 
				
			||||||
 | 
						</button>
 | 
				
			||||||
 | 
					{/if}
 | 
				
			||||||
							
								
								
									
										17
									
								
								src/lib/components/ui/button/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					import Root, {
 | 
				
			||||||
 | 
						type ButtonProps,
 | 
				
			||||||
 | 
						type ButtonSize,
 | 
				
			||||||
 | 
						type ButtonVariant,
 | 
				
			||||||
 | 
						buttonVariants,
 | 
				
			||||||
 | 
					} from "./button.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
						Root,
 | 
				
			||||||
 | 
						type ButtonProps as Props,
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						Root as Button,
 | 
				
			||||||
 | 
						buttonVariants,
 | 
				
			||||||
 | 
						type ButtonProps,
 | 
				
			||||||
 | 
						type ButtonSize,
 | 
				
			||||||
 | 
						type ButtonVariant,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										38
									
								
								src/lib/components/ui/dialog/dialog-content.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import { Dialog as DialogPrimitive, type WithoutChildrenOrChild } from "bits-ui";
 | 
				
			||||||
 | 
						import X from "lucide-svelte/icons/x";
 | 
				
			||||||
 | 
						import type { Snippet } from "svelte";
 | 
				
			||||||
 | 
						import * as Dialog from "./index.js";
 | 
				
			||||||
 | 
						import { cn } from "$lib/utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							ref = $bindable(null),
 | 
				
			||||||
 | 
							class: className,
 | 
				
			||||||
 | 
							portalProps,
 | 
				
			||||||
 | 
							children,
 | 
				
			||||||
 | 
							...restProps
 | 
				
			||||||
 | 
						}: WithoutChildrenOrChild<DialogPrimitive.ContentProps> & {
 | 
				
			||||||
 | 
							portalProps?: DialogPrimitive.PortalProps;
 | 
				
			||||||
 | 
							children: Snippet;
 | 
				
			||||||
 | 
						} = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Dialog.Portal {...portalProps}>
 | 
				
			||||||
 | 
						<Dialog.Overlay />
 | 
				
			||||||
 | 
						<DialogPrimitive.Content
 | 
				
			||||||
 | 
							bind:ref
 | 
				
			||||||
 | 
							class={cn(
 | 
				
			||||||
 | 
								"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] bg-background fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg",
 | 
				
			||||||
 | 
								className
 | 
				
			||||||
 | 
							)}
 | 
				
			||||||
 | 
							{...restProps}
 | 
				
			||||||
 | 
						>
 | 
				
			||||||
 | 
							{@render children?.()}
 | 
				
			||||||
 | 
							<DialogPrimitive.Close
 | 
				
			||||||
 | 
								class="ring-offset-background focus:ring-ring absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none"
 | 
				
			||||||
 | 
							>
 | 
				
			||||||
 | 
								<X class="size-4" />
 | 
				
			||||||
 | 
								<span class="sr-only">Close</span>
 | 
				
			||||||
 | 
							</DialogPrimitive.Close>
 | 
				
			||||||
 | 
						</DialogPrimitive.Content>
 | 
				
			||||||
 | 
					</Dialog.Portal>
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/lib/components/ui/dialog/dialog-description.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import { Dialog as DialogPrimitive } from "bits-ui";
 | 
				
			||||||
 | 
						import { cn } from "$lib/utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							ref = $bindable(null),
 | 
				
			||||||
 | 
							class: className,
 | 
				
			||||||
 | 
							...restProps
 | 
				
			||||||
 | 
						}: DialogPrimitive.DescriptionProps = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<DialogPrimitive.Description
 | 
				
			||||||
 | 
						bind:ref
 | 
				
			||||||
 | 
						class={cn("text-muted-foreground text-sm", className)}
 | 
				
			||||||
 | 
						{...restProps}
 | 
				
			||||||
 | 
					/>
 | 
				
			||||||
							
								
								
									
										20
									
								
								src/lib/components/ui/dialog/dialog-footer.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import type { WithElementRef } from "bits-ui";
 | 
				
			||||||
 | 
						import type { HTMLAttributes } from "svelte/elements";
 | 
				
			||||||
 | 
						import { cn } from "$lib/utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							ref = $bindable(null),
 | 
				
			||||||
 | 
							class: className,
 | 
				
			||||||
 | 
							children,
 | 
				
			||||||
 | 
							...restProps
 | 
				
			||||||
 | 
						}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div
 | 
				
			||||||
 | 
						bind:this={ref}
 | 
				
			||||||
 | 
						class={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
 | 
				
			||||||
 | 
						{...restProps}
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						{@render children?.()}
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										20
									
								
								src/lib/components/ui/dialog/dialog-header.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import type { HTMLAttributes } from "svelte/elements";
 | 
				
			||||||
 | 
						import type { WithElementRef } from "bits-ui";
 | 
				
			||||||
 | 
						import { cn } from "$lib/utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							ref = $bindable(null),
 | 
				
			||||||
 | 
							class: className,
 | 
				
			||||||
 | 
							children,
 | 
				
			||||||
 | 
							...restProps
 | 
				
			||||||
 | 
						}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div
 | 
				
			||||||
 | 
						bind:this={ref}
 | 
				
			||||||
 | 
						class={cn("flex flex-col space-y-1.5 text-center sm:text-left", className)}
 | 
				
			||||||
 | 
						{...restProps}
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						{@render children?.()}
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/lib/components/ui/dialog/dialog-overlay.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import { Dialog as DialogPrimitive } from "bits-ui";
 | 
				
			||||||
 | 
						import { cn } from "$lib/utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							ref = $bindable(null),
 | 
				
			||||||
 | 
							class: className,
 | 
				
			||||||
 | 
							...restProps
 | 
				
			||||||
 | 
						}: DialogPrimitive.OverlayProps = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<DialogPrimitive.Overlay
 | 
				
			||||||
 | 
						bind:ref
 | 
				
			||||||
 | 
						class={cn(
 | 
				
			||||||
 | 
							"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0  fixed inset-0 z-50 bg-black/80",
 | 
				
			||||||
 | 
							className
 | 
				
			||||||
 | 
						)}
 | 
				
			||||||
 | 
						{...restProps}
 | 
				
			||||||
 | 
					/>
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/lib/components/ui/dialog/dialog-title.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import { Dialog as DialogPrimitive } from "bits-ui";
 | 
				
			||||||
 | 
						import { cn } from "$lib/utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							ref = $bindable(null),
 | 
				
			||||||
 | 
							class: className,
 | 
				
			||||||
 | 
							...restProps
 | 
				
			||||||
 | 
						}: DialogPrimitive.TitleProps = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<DialogPrimitive.Title
 | 
				
			||||||
 | 
						bind:ref
 | 
				
			||||||
 | 
						class={cn("text-lg font-semibold leading-none tracking-tight", className)}
 | 
				
			||||||
 | 
						{...restProps}
 | 
				
			||||||
 | 
					/>
 | 
				
			||||||
							
								
								
									
										37
									
								
								src/lib/components/ui/dialog/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					import { Dialog as DialogPrimitive } from "bits-ui";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Title from "./dialog-title.svelte";
 | 
				
			||||||
 | 
					import Footer from "./dialog-footer.svelte";
 | 
				
			||||||
 | 
					import Header from "./dialog-header.svelte";
 | 
				
			||||||
 | 
					import Overlay from "./dialog-overlay.svelte";
 | 
				
			||||||
 | 
					import Content from "./dialog-content.svelte";
 | 
				
			||||||
 | 
					import Description from "./dialog-description.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Root = DialogPrimitive.Root;
 | 
				
			||||||
 | 
					const Trigger = DialogPrimitive.Trigger;
 | 
				
			||||||
 | 
					const Close = DialogPrimitive.Close;
 | 
				
			||||||
 | 
					const Portal = DialogPrimitive.Portal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
						Root,
 | 
				
			||||||
 | 
						Title,
 | 
				
			||||||
 | 
						Portal,
 | 
				
			||||||
 | 
						Footer,
 | 
				
			||||||
 | 
						Header,
 | 
				
			||||||
 | 
						Trigger,
 | 
				
			||||||
 | 
						Overlay,
 | 
				
			||||||
 | 
						Content,
 | 
				
			||||||
 | 
						Description,
 | 
				
			||||||
 | 
						Close,
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						Root as Dialog,
 | 
				
			||||||
 | 
						Title as DialogTitle,
 | 
				
			||||||
 | 
						Portal as DialogPortal,
 | 
				
			||||||
 | 
						Footer as DialogFooter,
 | 
				
			||||||
 | 
						Header as DialogHeader,
 | 
				
			||||||
 | 
						Trigger as DialogTrigger,
 | 
				
			||||||
 | 
						Overlay as DialogOverlay,
 | 
				
			||||||
 | 
						Content as DialogContent,
 | 
				
			||||||
 | 
						Description as DialogDescription,
 | 
				
			||||||
 | 
						Close as DialogClose,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										7
									
								
								src/lib/components/ui/input/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					import Root from "./input.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
						Root,
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						Root as Input,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										22
									
								
								src/lib/components/ui/input/input.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import type { HTMLInputAttributes } from "svelte/elements";
 | 
				
			||||||
 | 
						import type { WithElementRef } from "bits-ui";
 | 
				
			||||||
 | 
						import { cn } from "$lib/utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							ref = $bindable(null),
 | 
				
			||||||
 | 
							value = $bindable(),
 | 
				
			||||||
 | 
							class: className,
 | 
				
			||||||
 | 
							...restProps
 | 
				
			||||||
 | 
						}: WithElementRef<HTMLInputAttributes> = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<input
 | 
				
			||||||
 | 
						bind:this={ref}
 | 
				
			||||||
 | 
						class={cn(
 | 
				
			||||||
 | 
							"border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-base file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
 | 
				
			||||||
 | 
							className
 | 
				
			||||||
 | 
						)}
 | 
				
			||||||
 | 
						bind:value
 | 
				
			||||||
 | 
						{...restProps}
 | 
				
			||||||
 | 
					/>
 | 
				
			||||||
							
								
								
									
										7
									
								
								src/lib/components/ui/label/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					import Root from "./label.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
						Root,
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						Root as Label,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/lib/components/ui/label/label.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import { Label as LabelPrimitive } from "bits-ui";
 | 
				
			||||||
 | 
						import { cn } from "$lib/utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let {
 | 
				
			||||||
 | 
							ref = $bindable(null),
 | 
				
			||||||
 | 
							class: className,
 | 
				
			||||||
 | 
							...restProps
 | 
				
			||||||
 | 
						}: LabelPrimitive.RootProps = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<LabelPrimitive.Root
 | 
				
			||||||
 | 
						bind:ref
 | 
				
			||||||
 | 
						class={cn(
 | 
				
			||||||
 | 
							"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
 | 
				
			||||||
 | 
							className
 | 
				
			||||||
 | 
						)}
 | 
				
			||||||
 | 
						{...restProps}
 | 
				
			||||||
 | 
					/>
 | 
				
			||||||
							
								
								
									
										1
									
								
								src/lib/components/ui/sonner/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					export { default as Toaster } from "./sonner.svelte";
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/lib/components/ui/sonner/sonner.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import { Toaster as Sonner, type ToasterProps as SonnerProps } from "svelte-sonner";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let restProps: SonnerProps = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Sonner
 | 
				
			||||||
 | 
						theme={"light"}
 | 
				
			||||||
 | 
						class="toaster group"
 | 
				
			||||||
 | 
						toastOptions={{
 | 
				
			||||||
 | 
							classes: {
 | 
				
			||||||
 | 
								toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
 | 
				
			||||||
 | 
								description: "group-[.toast]:text-muted-foreground",
 | 
				
			||||||
 | 
								actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
 | 
				
			||||||
 | 
								cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}}
 | 
				
			||||||
 | 
						{...restProps}
 | 
				
			||||||
 | 
					/>
 | 
				
			||||||
							
								
								
									
										17
									
								
								src/lib/cutils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					import { Filesystem } from "@capacitor/filesystem";
 | 
				
			||||||
 | 
					import type { GetUriOptions, MkdirOptions } from "@capacitor/filesystem";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function checkFileExists(getUriOptions: GetUriOptions): Promise<boolean> {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        await Filesystem.stat(getUriOptions);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    } catch (_) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function createDirectory(mkdirOptions: MkdirOptions) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        await Filesystem.mkdir(mkdirOptions);
 | 
				
			||||||
 | 
					    } catch (_) { }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								src/lib/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					// place files you want to import through the `$lib` alias in this folder.
 | 
				
			||||||
							
								
								
									
										70
									
								
								src/lib/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					import { type ClassValue, clsx } from "clsx";
 | 
				
			||||||
 | 
					import { twMerge } from "tailwind-merge";
 | 
				
			||||||
 | 
					import { cubicOut } from "svelte/easing";
 | 
				
			||||||
 | 
					import type { TransitionConfig } from "svelte/transition";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function cn(...inputs: ClassValue[]) {
 | 
				
			||||||
 | 
					    return twMerge(clsx(inputs));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FlyAndScaleParams = {
 | 
				
			||||||
 | 
					    y?: number;
 | 
				
			||||||
 | 
					    x?: number;
 | 
				
			||||||
 | 
					    start?: number;
 | 
				
			||||||
 | 
					    duration?: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const flyAndScale = (
 | 
				
			||||||
 | 
					    node: Element,
 | 
				
			||||||
 | 
					    params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
 | 
				
			||||||
 | 
					): TransitionConfig => {
 | 
				
			||||||
 | 
					    const style = getComputedStyle(node);
 | 
				
			||||||
 | 
					    const transform = style.transform === "none" ? "" : style.transform;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const scaleConversion = (
 | 
				
			||||||
 | 
					        valueA: number,
 | 
				
			||||||
 | 
					        scaleA: [number, number],
 | 
				
			||||||
 | 
					        scaleB: [number, number]
 | 
				
			||||||
 | 
					    ) => {
 | 
				
			||||||
 | 
					        const [minA, maxA] = scaleA;
 | 
				
			||||||
 | 
					        const [minB, maxB] = scaleB;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const percentage = (valueA - minA) / (maxA - minA);
 | 
				
			||||||
 | 
					        const valueB = percentage * (maxB - minB) + minB;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return valueB;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const styleToString = (
 | 
				
			||||||
 | 
					        style: Record<string, number | string | undefined>
 | 
				
			||||||
 | 
					    ): string => {
 | 
				
			||||||
 | 
					        return Object.keys(style).reduce((str, key) => {
 | 
				
			||||||
 | 
					            if (style[key] === undefined) return str;
 | 
				
			||||||
 | 
					            return str + key + ":" + style[key] + ";";
 | 
				
			||||||
 | 
					        }, "");
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        duration: params.duration ?? 200,
 | 
				
			||||||
 | 
					        delay: 0,
 | 
				
			||||||
 | 
					        css: (t) => {
 | 
				
			||||||
 | 
					            const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]);
 | 
				
			||||||
 | 
					            const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]);
 | 
				
			||||||
 | 
					            const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return styleToString({
 | 
				
			||||||
 | 
					                transform:
 | 
				
			||||||
 | 
					                    transform +
 | 
				
			||||||
 | 
					                    "translate3d(" +
 | 
				
			||||||
 | 
					                    x +
 | 
				
			||||||
 | 
					                    "px, " +
 | 
				
			||||||
 | 
					                    y +
 | 
				
			||||||
 | 
					                    "px, 0) scale(" +
 | 
				
			||||||
 | 
					                    scale +
 | 
				
			||||||
 | 
					                    ")",
 | 
				
			||||||
 | 
					                opacity: t,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        easing: cubicOut,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										30
									
								
								src/routes/+layout.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import '../app.css';
 | 
				
			||||||
 | 
						import { Toaster } from '$lib/components/ui/sonner';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let { children } = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Toaster />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="flex flex-col h-screen">
 | 
				
			||||||
 | 
						<div id="header"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<div class="overflow-y-auto">
 | 
				
			||||||
 | 
							{@render children()}
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<div id="footer"></div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
						#header {
 | 
				
			||||||
 | 
							height: var(--safe-area-inset-top);
 | 
				
			||||||
 | 
							background-color: white;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#footer {
 | 
				
			||||||
 | 
							height: var(--safe-area-inset-bottom);
 | 
				
			||||||
 | 
							background-color: white;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										1
									
								
								src/routes/+layout.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					export const prerender = true;
 | 
				
			||||||
							
								
								
									
										316
									
								
								src/routes/+page.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,316 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import * as Dialog from '$lib/components/ui/dialog';
 | 
				
			||||||
 | 
						import { Input } from '$lib/components/ui/input';
 | 
				
			||||||
 | 
						import { Label } from '$lib/components/ui/label';
 | 
				
			||||||
 | 
						import { Button, buttonVariants } from '$lib/components/ui/button';
 | 
				
			||||||
 | 
						import ScanCapture from '$lib/ScanCapture.svelte';
 | 
				
			||||||
 | 
						import { cn } from '$lib/utils';
 | 
				
			||||||
 | 
						import { toast } from 'svelte-sonner';
 | 
				
			||||||
 | 
						import { Filesystem, Directory, Encoding } from '@capacitor/filesystem';
 | 
				
			||||||
 | 
						import { checkFileExists, createDirectory } from '$lib/cutils';
 | 
				
			||||||
 | 
						import { Haptics, ImpactStyle } from '@capacitor/haptics';
 | 
				
			||||||
 | 
						import { SvelteMap } from 'svelte/reactivity';
 | 
				
			||||||
 | 
						import { onMount } from 'svelte';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let showdialog = $state(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let focused = $state(false);
 | 
				
			||||||
 | 
						let confirmation = $state(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const formValues: SvelteMap<string, string | undefined> = new SvelteMap();
 | 
				
			||||||
 | 
						let sessioncount = $state(0);
 | 
				
			||||||
 | 
						let daycount = $state(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let selected = $state('service');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function onscan(value: string) {
 | 
				
			||||||
 | 
							// Set as empty if undefined
 | 
				
			||||||
 | 
							if (formValues.get(selected) == undefined) {
 | 
				
			||||||
 | 
								formValues.set(selected, '');
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (value == 'Home') {
 | 
				
			||||||
 | 
								showdialog = !showdialog;
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (value == 'Delete') {
 | 
				
			||||||
 | 
								reset();
 | 
				
			||||||
 | 
								toast.success('Cleared');
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Advance to next input field
 | 
				
			||||||
 | 
							if (value == 'Tab' || value == 'Enter') {
 | 
				
			||||||
 | 
								if (selected == 'service') {
 | 
				
			||||||
 | 
									selected = 'serial';
 | 
				
			||||||
 | 
								} else if (selected == 'serial') {
 | 
				
			||||||
 | 
									selected = 'description';
 | 
				
			||||||
 | 
								} else if (selected == 'description') {
 | 
				
			||||||
 | 
									selected = 'manufacturer';
 | 
				
			||||||
 | 
								} else if (selected == 'manufacturer') {
 | 
				
			||||||
 | 
									selected = 'model';
 | 
				
			||||||
 | 
								} else if (selected == 'model') {
 | 
				
			||||||
 | 
									selected = 'condition';
 | 
				
			||||||
 | 
								} else if (confirmation == false) {
 | 
				
			||||||
 | 
									confirmation = true;
 | 
				
			||||||
 | 
								} else if (confirmation == true) {
 | 
				
			||||||
 | 
									save();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Cancel confirmation
 | 
				
			||||||
 | 
							if (value == 'Backspace' && confirmation == true) {
 | 
				
			||||||
 | 
								confirmation = false;
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Go back to the previous input field
 | 
				
			||||||
 | 
							if (value == 'Backspace' && formValues.get(selected)?.length == 0) {
 | 
				
			||||||
 | 
								if (selected == 'condition') {
 | 
				
			||||||
 | 
									selected = 'model';
 | 
				
			||||||
 | 
								} else if (selected == 'model') {
 | 
				
			||||||
 | 
									selected = 'manufacturer';
 | 
				
			||||||
 | 
								} else if (selected == 'manufacturer') {
 | 
				
			||||||
 | 
									selected = 'description';
 | 
				
			||||||
 | 
								} else if (selected == 'description') {
 | 
				
			||||||
 | 
									selected = 'serial';
 | 
				
			||||||
 | 
								} else if (selected == 'serial') {
 | 
				
			||||||
 | 
									selected = 'service';
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Subtract one from the current input
 | 
				
			||||||
 | 
							if (value == 'Backspace') {
 | 
				
			||||||
 | 
								formValues.set(selected, formValues.get(selected)?.slice(0, -1));
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Append current input with new text
 | 
				
			||||||
 | 
							formValues.set(selected, formValues.get(selected) + value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						async function onsubmit(event: SubmitEvent & { currentTarget: EventTarget & HTMLFormElement }) {
 | 
				
			||||||
 | 
							event.preventDefault();
 | 
				
			||||||
 | 
							Haptics.impact({ style: ImpactStyle.Medium });
 | 
				
			||||||
 | 
							confirmation = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						async function save() {
 | 
				
			||||||
 | 
							Haptics.impact({ style: ImpactStyle.Medium });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Create directory
 | 
				
			||||||
 | 
							await createDirectory({
 | 
				
			||||||
 | 
								path: 'inventory',
 | 
				
			||||||
 | 
								directory: Directory.Documents
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const filename = `inventory/${new Date().toLocaleDateString().replaceAll('/', '-')}.csv`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Check if CSV file exists
 | 
				
			||||||
 | 
							const exists = await checkFileExists({
 | 
				
			||||||
 | 
								path: filename,
 | 
				
			||||||
 | 
								directory: Directory.Documents
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Create file if it does not exist
 | 
				
			||||||
 | 
							if (!exists) {
 | 
				
			||||||
 | 
								await Filesystem.writeFile({
 | 
				
			||||||
 | 
									path: filename,
 | 
				
			||||||
 | 
									data: '',
 | 
				
			||||||
 | 
									directory: Directory.Documents,
 | 
				
			||||||
 | 
									encoding: Encoding.UTF8
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Append data to file
 | 
				
			||||||
 | 
							await Filesystem.appendFile({
 | 
				
			||||||
 | 
								path: filename,
 | 
				
			||||||
 | 
								data: `${formValues.get('service')},${formValues.get('serial')},${formValues.get('manufacturer')},${formValues.get('model')},${formValues.get('description')},${formValues.get('condition')},${new Date().toLocaleDateString()}\n`,
 | 
				
			||||||
 | 
								directory: Directory.Documents,
 | 
				
			||||||
 | 
								encoding: Encoding.UTF8
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sessioncount = sessioncount + 1;
 | 
				
			||||||
 | 
							daycount = daycount + 1;
 | 
				
			||||||
 | 
							toast.success('Added item to inventory');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Reset values
 | 
				
			||||||
 | 
							reset();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function reset() {
 | 
				
			||||||
 | 
							confirmation = false;
 | 
				
			||||||
 | 
							selected = 'service';
 | 
				
			||||||
 | 
							formValues.set('serial', '');
 | 
				
			||||||
 | 
							formValues.set('description', '');
 | 
				
			||||||
 | 
							formValues.set('service', '');
 | 
				
			||||||
 | 
							formValues.set('manufacturer', '');
 | 
				
			||||||
 | 
							formValues.set('model', '');
 | 
				
			||||||
 | 
							formValues.set('condition', '');
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						onMount(async () => {
 | 
				
			||||||
 | 
							const filename = `inventory/${new Date().toLocaleDateString().replaceAll('/', '-')}.csv`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Check if CSV file exists
 | 
				
			||||||
 | 
							const exists = await checkFileExists({
 | 
				
			||||||
 | 
								path: filename,
 | 
				
			||||||
 | 
								directory: Directory.Documents
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!exists) {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Read CSV file
 | 
				
			||||||
 | 
							const file = await Filesystem.readFile({
 | 
				
			||||||
 | 
								path: filename,
 | 
				
			||||||
 | 
								directory: Directory.Documents,
 | 
				
			||||||
 | 
								encoding: Encoding.UTF8
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Parse CSV file
 | 
				
			||||||
 | 
							if (typeof file.data !== 'string') {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const lines = file.data.split("\n");
 | 
				
			||||||
 | 
							daycount = lines.length - 1;
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<ScanCapture {onscan} bind:focused />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Dialog.Root bind:open={showdialog}>
 | 
				
			||||||
 | 
						<Dialog.Content
 | 
				
			||||||
 | 
							onEscapeKeydown={(e) => {
 | 
				
			||||||
 | 
								e.preventDefault();
 | 
				
			||||||
 | 
							}}
 | 
				
			||||||
 | 
						>
 | 
				
			||||||
 | 
							<Dialog.Header>
 | 
				
			||||||
 | 
								<Dialog.Title>Stats</Dialog.Title>
 | 
				
			||||||
 | 
								<div class="grid grid-cols-2 gap-2 py-4">
 | 
				
			||||||
 | 
									<p>day count:</p>
 | 
				
			||||||
 | 
									<p>{daycount}</p>
 | 
				
			||||||
 | 
									<p>session count:</p>
 | 
				
			||||||
 | 
									<p>{sessioncount}</p>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
								<Button
 | 
				
			||||||
 | 
									type="button"
 | 
				
			||||||
 | 
									class={cn(buttonVariants({ variant: 'outline' }), 'text-black cursor-pointer')}
 | 
				
			||||||
 | 
									onclick={() => {
 | 
				
			||||||
 | 
										sessioncount = 0;
 | 
				
			||||||
 | 
										toast.success('Session count reset');
 | 
				
			||||||
 | 
									}}>Reset session count</Button
 | 
				
			||||||
 | 
								>
 | 
				
			||||||
 | 
							</Dialog.Header>
 | 
				
			||||||
 | 
						</Dialog.Content>
 | 
				
			||||||
 | 
					</Dialog.Root>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<form class="flex flex-col gap-4 py-2 px-3 py-4" {onsubmit}>
 | 
				
			||||||
 | 
						<div class="flex gap-2 items-center">
 | 
				
			||||||
 | 
							<Label class="basis-1/4" for="service">Asset Tag</Label>
 | 
				
			||||||
 | 
							<Input
 | 
				
			||||||
 | 
								id="service"
 | 
				
			||||||
 | 
								name="service"
 | 
				
			||||||
 | 
								type="text"
 | 
				
			||||||
 | 
								disabled={confirmation}
 | 
				
			||||||
 | 
								class={cn(!focused && selected == 'service' && 'ring-offset-2 ring-2 ring-green-600')}
 | 
				
			||||||
 | 
								bind:value={() => formValues.get('service'), (v) => formValues.set('service', v)}
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="flex gap-2 items-center">
 | 
				
			||||||
 | 
							<Label class="basis-1/4" for="serial">Serial #</Label>
 | 
				
			||||||
 | 
							<Input
 | 
				
			||||||
 | 
								id="serial"
 | 
				
			||||||
 | 
								name="serial"
 | 
				
			||||||
 | 
								type="text"
 | 
				
			||||||
 | 
								disabled={confirmation}
 | 
				
			||||||
 | 
								class={cn(!focused && selected == 'serial' && 'ring-offset-2 ring-2 ring-green-600')}
 | 
				
			||||||
 | 
								bind:value={() => formValues.get('serial'), (v) => formValues.set('serial', v)}
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="flex gap-2 items-center">
 | 
				
			||||||
 | 
							<Label class="basis-1/4" for="description">Machine Type</Label>
 | 
				
			||||||
 | 
							<Input
 | 
				
			||||||
 | 
								id="description"
 | 
				
			||||||
 | 
								name="description"
 | 
				
			||||||
 | 
								type="text"
 | 
				
			||||||
 | 
								disabled={confirmation}
 | 
				
			||||||
 | 
								class={cn(!focused && selected == 'description' && 'ring-offset-2 ring-2 ring-green-600')}
 | 
				
			||||||
 | 
								bind:value={() => formValues.get('description'), (v) => formValues.set('description', v)}
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="flex gap-2 items-center">
 | 
				
			||||||
 | 
							<Label class="basis-1/4" for="manufacturer">Maker</Label>
 | 
				
			||||||
 | 
							<Input
 | 
				
			||||||
 | 
								id="manufacturer"
 | 
				
			||||||
 | 
								name="manufacturer"
 | 
				
			||||||
 | 
								type="text"
 | 
				
			||||||
 | 
								disabled={confirmation}
 | 
				
			||||||
 | 
								class={cn(!focused && selected == 'manufacturer' && 'ring-offset-2 ring-2 ring-green-600')}
 | 
				
			||||||
 | 
								bind:value={() => formValues.get('manufacturer'), (v) => formValues.set('manufacturer', v)}
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="flex gap-2 items-center">
 | 
				
			||||||
 | 
							<Label class="basis-1/4" for="model">Model</Label>
 | 
				
			||||||
 | 
							<Input
 | 
				
			||||||
 | 
								id="model"
 | 
				
			||||||
 | 
								name="model"
 | 
				
			||||||
 | 
								type="text"
 | 
				
			||||||
 | 
								disabled={confirmation}
 | 
				
			||||||
 | 
								class={cn(!focused && selected == 'model' && 'ring-offset-2 ring-2 ring-green-600')}
 | 
				
			||||||
 | 
								bind:value={() => formValues.get('model'), (v) => formValues.set('model', v)}
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="flex gap-2 items-center">
 | 
				
			||||||
 | 
							<Label class="basis-1/4" for="condition">Condition</Label>
 | 
				
			||||||
 | 
							<Input
 | 
				
			||||||
 | 
								id="condition"
 | 
				
			||||||
 | 
								name="condition"
 | 
				
			||||||
 | 
								type="text"
 | 
				
			||||||
 | 
								disabled={confirmation}
 | 
				
			||||||
 | 
								class={cn(!focused && selected == 'condition' && 'ring-offset-2 ring-2 ring-green-600')}
 | 
				
			||||||
 | 
								bind:value={() => formValues.get('condition'), (v) => formValues.set('condition', v)}
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						{#if confirmation}
 | 
				
			||||||
 | 
							<div class="flex flex-col gap-2">
 | 
				
			||||||
 | 
								<Button
 | 
				
			||||||
 | 
									type="button"
 | 
				
			||||||
 | 
									class={cn(buttonVariants({ variant: 'outline' }), 'text-black cursor-pointer')}
 | 
				
			||||||
 | 
									onclick={() => {
 | 
				
			||||||
 | 
										reset();
 | 
				
			||||||
 | 
										toast.success('Canceled');
 | 
				
			||||||
 | 
									}}>Cancel</Button
 | 
				
			||||||
 | 
								>
 | 
				
			||||||
 | 
								<Button type="button" class="cursor-pointer" onclick={() => save()}>Confirm</Button>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
						{:else}
 | 
				
			||||||
 | 
							<div class="flex flex-col gap-2">
 | 
				
			||||||
 | 
								<div class="flex justify-center gap-1">
 | 
				
			||||||
 | 
									<Button
 | 
				
			||||||
 | 
										type="button"
 | 
				
			||||||
 | 
										class={cn(buttonVariants({ variant: 'outline' }), 'text-black cursor-pointer grow')}
 | 
				
			||||||
 | 
										onclick={() => {
 | 
				
			||||||
 | 
											showdialog = !showdialog;
 | 
				
			||||||
 | 
										}}>Stats</Button
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
									<Button
 | 
				
			||||||
 | 
										type="button"
 | 
				
			||||||
 | 
										class={cn(buttonVariants({ variant: 'outline' }), 'text-black cursor-pointer grow')}
 | 
				
			||||||
 | 
										onclick={() => {
 | 
				
			||||||
 | 
											reset();
 | 
				
			||||||
 | 
											toast.success('Cleared');
 | 
				
			||||||
 | 
										}}>Reset</Button
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
								<Button type="submit" class="cursor-pointer">Submit</Button>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
						{/if}
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								static/favicon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.5 KiB  |