support javadoc generation
diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml
new file mode 100644
index 0000000..2af762a
--- /dev/null
+++ b/.github/workflows/javadoc.yml
@@ -0,0 +1,42 @@
+name: Deploy JavaDoc to Pages
+
+on:
+  push:
+    branches: ["master"]
+  workflow_dispatch:
+
+permissions:
+  contents: read
+  pages: write
+  id-token: write
+
+concurrency:
+  group: "pages"
+  cancel-in-progress: true
+
+jobs:
+  deploy:
+    environment:
+      name: github-pages
+      url: ${{ steps.deployment.outputs.page_url }}
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+      - name: Setup Pages
+        uses: actions/configure-pages@v2
+      - name: Setup Java JDK
+        uses: actions/setup-java@v3.9.0
+        with:
+          java-version: 11
+          distribution: adopt
+      - name: Gradle Build Action
+        run: ./gradlew :FaceShared:generateReleaseJavadoc
+      - name: Upload artifact
+        uses: actions/upload-pages-artifact@v1
+        with:
+          # Upload entire repository
+          path: 'FaceShared/build/docs/'
+      - name: Deploy to GitHub Pages
+        id: deployment
+        uses: actions/deploy-pages@v1
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 360e6d4..150a43b 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="JavadocGenerationManager">
+    <option name="OUTPUT_DIRECTORY" value="$USER_HOME$/Downloads/javadoc" />
+    <option name="OPTION_INCLUDE_LIBS" value="true" />
+  </component>
   <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
diff --git a/FaceShared/build.gradle b/FaceShared/build.gradle
index 11c88ed..e979a9e 100644
--- a/FaceShared/build.gradle
+++ b/FaceShared/build.gradle
@@ -2,6 +2,25 @@
 	id 'com.android.library'
 }
 
+// https://stackoverflow.com/a/29164335, https://stackoverflow.com/a/52286740, https://stackoverflow.com/a/71848953, https://stackoverflow.com/a/63547141
+android.libraryVariants.all { variant ->
+	project.tasks.create("generate${variant.name.capitalize()}Javadoc", Javadoc) {
+		description "Generates Javadoc for $variant.name."
+		source = variant.sourceSets.collect { it.java.sourceFiles }.inject { m, i -> m + i }
+		doFirst {
+			classpath = project.files(variant.javaCompileProvider.get().classpath.files,
+					project.android.getBootClasspath())
+		}
+		exclude "**/R"
+		exclude "**/R.**"
+		exclude "**/R\$**"
+		exclude "**/BuildConfig*"
+		ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
+		options.links("https://d.android.com/reference/")
+		options.linksOffline('https://d.android.com/reference/', 'https://d.android.com/reference/androidx/')
+	}
+}
+
 android {
 	namespace 'com.libremobileos.yifan.face.shared'
 	compileSdk 33
diff --git a/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceDetector.java b/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceDetector.java
index 9059a49..b6408f2 100644
--- a/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceDetector.java
+++ b/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceDetector.java
@@ -132,13 +132,13 @@
 		}
 
 		/**
-		 * A sortable score for how good the recognition is relative to others. Higher should be better. Min: 0f Max: 1.0f
+		 * @return A sortable score for how good the recognition is relative to others. Higher should be better. Min: 0f Max: 1.0f
 		 */
 		public Float getConfidence() {
 			return confidence;
 		}
 
-		/** Optional location within the source image for the location of the recognized object. */
+		/** @return Optional location within the source image for the location of the recognized object. */
 		public RectF getLocation() {
 			return new RectF(location);
 		}
@@ -216,7 +216,7 @@
 	/**
 	 * Detect multiple faces in an {@link InputImage} and return their locations.
 	 * @param input Image, processed with {@link InputImageProcessor}
-	 * @return List of <a href="#{@link}">{@link Face}</a> objects
+	 * @return List of {@link Face} objects
 	 */
 	public List<Face> detectFaces(InputImage input) {
 		try {
diff --git a/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceFinder.java b/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceFinder.java
index 4c5c15f..8e6cd9a 100644
--- a/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceFinder.java
+++ b/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceFinder.java
@@ -24,10 +24,10 @@
 import java.util.List;
 
 /**
- * Combination of <a href="{@link}">{@link FaceDetector}</a> and <a href="{@link}">{@link FaceScanner}</a>
+ * Combination of {@link FaceDetector} and {@link FaceScanner}
  * for workloads where both face detection and face scanning are required.
  * However, this class makes no assumptions about the workload and is therefore bare-bones.
- * Because of this, usage of an task-specific class like <a href="{@link}">{@link FaceRecognizer}</a>
+ * Because of this, usage of an task-specific class like {@link FaceRecognizer}
  * is highly recommended, unless these do not fit your use case.
  */
 public class FaceFinder {
diff --git a/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceRecognizer.java b/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceRecognizer.java
index 0500dcc..755a967 100644
--- a/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceRecognizer.java
+++ b/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceRecognizer.java
@@ -26,7 +26,7 @@
 import java.util.Set;
 
 /**
- * Task-specific API for detecting & recognizing faces in an image.
+ * Task-specific API for detecting &amp; recognizing faces in an image.
  * Uses {@link FaceFinder} to detect and scan faces, {@link FaceStorageBackend} to store and retrieve the saved faces and returns the optimal result.
  */
 public class FaceRecognizer {
@@ -152,14 +152,14 @@
 		}
 
 		/**
-		 * A sortable score for how good the detection (NOT recognition, that's {@link #getDistance()}) is relative to others. Higher should be better. Min: 0f Max: 1.0f
+		 * @return A sortable score for how good the detection (NOT recognition, that's {@link #getDistance()}) is relative to others. Higher should be better. Min: 0f Max: 1.0f
 		 */
 		public float getConfidence() {
 			return confidence;
 		}
 
 		/**
-		 * How many models detected the face.
+		 * @return How many models detected the face.
 		 */
 		public int getModelCount() {
 			return modelCount;
diff --git a/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceScanner.java b/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceScanner.java
index ddb5c16..22287a7 100644
--- a/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceScanner.java
+++ b/FaceShared/src/main/java/com/libremobileos/yifan/face/FaceScanner.java
@@ -76,7 +76,7 @@
 	/**
 	 * Processes Bitmaps to compatible format.
 	 * This class supports 2 modes of operation:<br>
-	 * 1. Preprocess perfectly cropped {@link Bitmap} to AI-compatible format, using the static method {@link #process(Bitmap, int)}</a><br>
+	 * 1. Preprocess perfectly cropped {@link Bitmap} to AI-compatible format, using the static method {@link #process(Bitmap, int)}<br>
 	 * 2. Crop one large {@link Bitmap} to multiple {@link InputImage}s using bounds inside {@link RectF} objects,
 	 *    with {@link #InputImageProcessor(Bitmap, int)} and {@link #process(RectF)}.
 	 *    This allows processing multiple faces on one {@link Bitmap}, for usage with {@link FaceDetector} and similar classes.
@@ -131,6 +131,7 @@
 		 * In normal mode of operation, we take a perfectly cropped {@link Bitmap} containing one face and process it.
 		 * This utility method uses sensorOrientation that was passed in the constructor and calls {@link #process(Bitmap, int)}
 		 * @param input Bitmap to process.
+		 * @return Converted {@link InputImage}
 		 * @see #process(Bitmap, int)
 		 */
 		public InputImage process(Bitmap input) {
diff --git a/settings.gradle b/settings.gradle
index eb46f77..72e3b45 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -14,4 +14,4 @@
 }
 rootProject.name = "FaceDetect"
 include ':app'
-include ':FaceShared'
+include ':FaceShared'
\ No newline at end of file