[![Maven Central](https://img.shields.io/maven-central/v/com.splendo.kaluga/base)](https://central.sonatype.com/search?q=g:com.splendo.kaluga) [![Build Status](https://app.bitrise.io/app/14b7d4be75507f70/status.svg?token=KawVB7619B-KRBdIADdplg&branch=master)](https://app.bitrise.io/app/14b7d4be75507f70)🤖 [![Build Status](https://app.bitrise.io/app/67ee1b576288ad31/status.svg?token=hUq90QsaCPe2nyWxyX1KGg&branch=master)](https://app.bitrise.io/app/67ee1b576288ad31)🍏

![kaluga logo](https://raw.githubusercontent.com/splendo/kaluga/b1198b0427046f7aa3de5f74fd2fcebd461eb6c1/logo/Logo.svg)

This project is named after the Kaluga, the world's biggest freshwater fish, which is found in the icy Amur river.

Kaluga's main goal is to provide access to common features used in cross-platform mobile app development, separated into modules such as architecture (MVVM), location, permissions, bluetooth etc.

To reach this goal it uses Kotlin, specifically [Kotlin Multiplatform](https://kotlinlang.org/docs/multiplatform.html) which allows running Kotlin code not just on JVM+Android, but also iOS/iPadOS, amongst others (inndeed some kaluga modules also work for Kotlin.js and/or JVM standalone).

Where appropriate coroutines and `Flow` are used in the API. This enables developers to use [cold streams](https://medium.com/@elizarov/cold-flows-hot-channels-d74769805f9) for a modern and efficient design.

While Kaluga modules can be used individually, together they form a comprehensive approach to cross-platform development with [shared native code](https://kotlinlang.org/docs/mpp-share-on-platforms.html) and native UIs, including SwiftUI and Compose.

### Short examples

With Kaluga it is possible to create cross-platform functionality in a few lines of code, that would normally take many lines of code even on just one platform.

Below are some examples, using a [`commonMain` source-set](https://kotlinlang.org/docs/mpp-dsl-reference.html#predefined-source-sets):

Scanning for nearby devices with Bluetooth LE:

```kotlin
// will auto request permissions and try to enable bluetooth
BluetoothBuilder().create().devices().collect {
    i("discovered device: $it") // log found device
}
```

Showing a spinner while doing some work:

```kotlin

suspend fun doWork(hudBuilder: HUD.Builder) {
    hudBuilder.presentDuring { // shows spinner while code in this block is running
        // simulate doing work
        delay(1000)
    }
}

```

in this case, since HUD is a UI component the builder needs to be configured on the platform side:
```kotlin
val builder = HUD.Builder() // same for iOS and Android
// ...
builder.subscribe(activity) // this needs be done in the Android source-set to bind the HUD to the lifecycle of the Activity
// ...
builder.unsubscribe(activity) // when the Activity is stopped
```

However Kaluga's [architecture module](architecture/) offers a cross-platform [`LifecycleViewModel`](architecture/src/commonMain/kotlin/viewmodel/LifecycleViewModel.kt) class (which extends `androidx.lifecycle.ViewModel` on Android) that will automatically bind the builder to its lifecycle:

```kotlin
// this can just be in the commonMain source
class HudViewModel(private val hudBuilder: HUD.Builder): BaseLifecycleViewModel(hudBuilder) {

    suspend fun doWork() =
        hudBuilder.presentDuring {
            delay(1000)
        }
}
```
### More examples

Kaluga contains [an example project](example/) that is used to test the developed modules.

## Using Kaluga

For starting a new project based on Kaluga see the [kaluga-starter repo](https://github.com/splendo/kaluga-starter), which shows how to do this step by step.

Kaluga is available on Maven Central. For example the Kaluga Alerts can be imported like this:

```kotlin
repositories {
    mavenCentral()
}
dependencies {
    implementation("com.splendo.kaluga:alerts:$kalugaVersion")
}
```

You can also use the `SNAPSHOT` version based on the latest in the `develop` branch:

```kotlin
repositories {
    maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}
dependencies {
    implementation("com.splendo.kaluga:alerts:$kalugaDevelopVersion-SNAPSHOT")
}
```

To use kaluga with SwiftUI and/or Combine we have a [repo with Sourcery templates](https://github.com/splendo/kaluga-swiftui) to generate some Swift code to help get you started.

### Available Modules

| Module                                                      | Usage                                                                              | Artifact Name                                  |
|-------------------------------------------------------------|------------------------------------------------------------------------------------|------------------------------------------------|
| [alerts](alerts/)                                           | Used for Showing Alert Dialogs                                                     | com.splendo.kaluga:alerts                      |
| [architecture](architecture/)                               | MVVM architecture                                                                  | com.splendo.kaluga:architecture                |
| [architecture-compose](architecture-compose/)               | Compose extensions for architecture                                                | com.splendo.kaluga:architecture-compose        |
| [base](base/)                                               | Core components of Kaluga. Contains threading, flowables and localization features | com.splendo.kaluga:base                        |
| [beacons](beacons/)                                         | Tracking the availability of Beacons using the Eddystone protocol                  | com.splendo.kaluga:beacons                     |
| [bluetooth](bluetooth/)                                     | Scanning for and communicating with BLE devices                                    | com.splendo.kaluga:bluetooth                   |
| [date-time](date-time/)                                     | Contains multiplatform classes to work with date and time                          | com.splendo.kaluga:date-time                   |
| [date-timepicker](date-time-picker/)                        | Used for showing a Date or Time Picker                                             | com.splendo.kaluga:date-time-picker            |
| [hud](hud/)                                                 | Used for showing a Loading indicator HUD                                           | com.splendo.kaluga:hud                         |
| [keyboard](keyboard/)                                       | Used for showing and hiding the keyboard                                           | com.splendo.kaluga:keyboard                    |
| [keyboard-compose](keyboard-compose/)                       | Compose extensions for keyboard                                                    | com.splendo.kaluga:keyboard-compose            |
| [links](links/)                                             | Used for decoding url into an object                                               | com.splendo.kaluga:links                       |
| [location](location/)                                       | Provides the User' geolocation                                                     | com.splendo.kaluga:location                    |
| [logging](logging/)                                         | Shared console logging                                                             | com.splendo.kaluga:logging                     |
| [media](media/)                                             | Playing audio/video                                                                | com.splendo.kaluga:media                       |
| [base-permissions](base-permissions/)                       | Managing permissions, used in conjunction with modules below                       | com.splendo.kaluga:base-permissions            |
| [bluetooth-permissions](bluetooth-permissions/)             | Managing bluetooth permissions                                                     | com.splendo.kaluga:bluetooth-permissions       |
| [calendar-permissions](calendar-permissions/)               | Managing calendar permissions                                                      | com.splendo.kaluga:calendar-permissions        |
| [camera-permissions](camera-permissions/)                   | Managing camera permissions                                                        | com.splendo.kaluga:camera-permissions          |
| [contacts-permissions](contacts-permissions/)               | Managing contacts permissions                                                      | com.splendo.kaluga:contacts-permissions        |
| [location-permissions](location-permissions/)               | Managing location permissions                                                      | com.splendo.kaluga:location-permissions        |
| [microphone-permissions](microphone-permissions/)           | Managing microphone permissions                                                    | com.splendo.kaluga:microphone-permissions      |
| [notifications-permissions](notifications-permissions/)     | Managing notifications permissions                                                 | com.splendo.kaluga:notifications-permissions   |
| [storage-permissions](storage-permissions/)                 | Managing storage permissions                                                       | com.splendo.kaluga:storage-permissions         |
| [resources](resources/)                                     | Provides shared Strings, Images, Colors and Fonts                                  | com.splendo.kaluga:resources                   |
| [resources-compose](resources-compose/)                     | Compose extensions for resources                                                   | com.splendo.kaluga:resources-compose           |
| [resources-databinding](resources-databinding/)             | Data Binding extensions for resources                                              | com.splendo.kaluga:resources-databinding       |
| [review](review/)                                           | Used for requesting the user to review the app                                     | com.splendo.kaluga:review                      |
| [scientific](scientific/)                                   | Scientific units and conversions                                                   | com.splendo.kaluga:scientific                  |
| [service](service/)                                         | Used for adding services to Kaluga                                                 | com.splendo.kaluga:service                     |
| [system](system/)                                           | System APIs such as network, audio, battery                                        | com.splendo.kaluga:system                      |
| [test-utils](test-utils/)                                   | Enables easier testing of Kaluga components                                        | com.splendo.kaluga:test-utils                  |
| [test-utils-base](test-utils-base/)                         | Enables easier testing of Kaluga components                                        | com.splendo.kaluga:test-utils-base             |
| [test-utils-alerts](test-utils-alerts/)                     | Enables easier testing of Alerts module                                            | com.splendo.kaluga:test-utils-alerts           |
| [test-utils-architecture](test-utils-architecture/)         | Enables easier testing of Architecture module                                      | com.splendo.kaluga:test-utils-architecture     |
| [test-utils-bluetooth](test-utils-bluetooth/)               | Enables easier testing of Bluetooth module                                         | com.splendo.kaluga:test-utils-bluetooth        |
| [test-utils-date-time-picker](test-utils-date-time-picker/) | Enables easier testing of Date Time Picker module                                  | com.splendo.kaluga:test-utils-date-time-picker |
| [test-utils-hud](test-utils-hud/)                           | Enables easier testing of HUD module                                               | com.splendo.kaluga:test-utils-hud              |
| [test-utils-keyboard](test-utils-keyboard/)                 | Enables easier testing of Keyboard module                                          | com.splendo.kaluga:test-utils-keyboard         |
| [test-utils-koin](test-utils-koin/)                         | Enables easier testing with Koin                                                   | com.splendo:kaluga.test-utils-koin             |
| [test-utils-location](test-utils-location/)                 | Enables easier testing of Location module                                          | com.splendo.kaluga:test-utils-location         |
| [test-utils-permissions](test-utils-permissions/)           | Enables easier testing of Permissions modules                                      | com.splendo.kaluga:test-utils-permissions      |
| [test-utils-resources](test-utils-resources/)               | Enables easier testing of Resources module                                         | com.splendo.kaluga:test-utils-resources        |
| [test-utils-service](test-utils-service/)                   | Enables easier testing of Service module                                           | com.splendo.kaluga:test-utils-service          |
| [test-utils-system](test-utils-system/)                     | Enables easier testing of System module                                            | com.splendo.kaluga:test-utils-system           |

### Friends of kaluga

Of course not every possible functionality is provided by kaluga. However, this is often because other good multiplatform libraries that work nicely with kaluga already exist. These use similar patterns such as coroutines and `Flow`, and include the following:

| Project                                                                       | Usage                                  |
|-------------------------------------------------------------------------------|----------------------------------------|
| [kotlin-firebase-sdk](https://github.com/GitLiveApp/firebase-kotlin-sdk)      | wraps most of the Firebase SDK APIs    |
| [multiplatform-settings](https://github.com/russhwolf/multiplatform-settings) | store key/value data                   |
| [SQLDelight](https://github.com/cashapp/sqldelight)                           | access SQLite (and other SQL database) |

Kaluga also uses some multiplatform libraries itself, so our thanks to:

| Project                                        | Usage                     |
|------------------------------------------------|---------------------------|
| [Napier](https://github.com/AAkira/Napier)     | powers the logging module |
| [Koin](https://insert-koin.io/)                | dependency injection      |

## Developing Kaluga

see [DEVELOP](DEVELOP.md).


# Nekome

![Master](https://github.com/Chesire/Nekome/workflows/Master/badge.svg)
[![Build Status](https://app.bitrise.io/app/9d4a9399b9f5d683/status.svg?token=9KwlEAgGeH0XqZ_LuwDJuA&branch=master)](https://app.bitrise.io/app/9d4a9399b9f5d683)
[![codecov](https://codecov.io/gh/Chesire/Nekome/branch/master/graph/badge.svg)](https://codecov.io/gh/Chesire/Nekome)

Nekome is an Android application that helps with tracking your anime and manga watch lists. Watch list data is handled by [Kitsu](https://kitsu.io/).

[](https://f-droid.org/packages/com.chesire.nekome/)
[](https://play.google.com/store/apps/details?id=com.chesire.nekome)

## Features

* Track Anime and Manga series progress
* Quickly update progress on series
* Search for new series to follow
* Light and Dark themes

## Tech Stack

* Support for Android 5.0+ (SDK 21+)
* Fully Kotlin
* Uses [Kitsu](https://kitsu.io/) to store information, all accessed through [their API](https://kitsu.docs.apiary.io/)
* [MVVM](https://developer.android.com/topic/libraries/architecture) for the architecture
* [Compose](https://developer.android.com/jetpack/compose) for the UI layer
* [Material3](https://developer.android.com/jetpack/compose/designsystems/material3) support for dynamic themes using Material 3
* [Hilt](https://dagger.dev/hilt/) for dependency injection
* [Retrofit](https://github.com/square/retrofit) to aid with API communicaton
* [Moshi](https://github.com/square/moshi) for parsing JSON
* [Coroutines](https://github.com/Kotlin/kotlinx.coroutines) to perform async tasks
* [Coil](https://github.com/coil-kt/coil) for async image loading
* [Detekt](https://github.com/arturbosch/detekt) & [ktlint](https://github.com/pinterest/ktlint) are used for static analysis

## Contribution

For contributing to the project, please feel free to [create an issue](https://github.com/Chesire/Nekome/issues/new) or submit a pull request.

## License

    Copyright (C) 2023 Troy Rijkaard

    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

    http://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.


PennMobile Android
===================

Penn's mobile app for Android, created in a partnership between Penn Labs and the UA.

## Features

* Interactive home page with events, polls, and posts
* View dining information, including hours and menus
* Book group study rooms (GSRs) and manage your bookings
* View college house laundry machine availability
* Check the capacity and business of fitness locations
* Access relevant campus information and support resources

## For Developers

Before making a pull request, it's important to lint the codebase to maintain readability. We use the default [ktlint formatter](https://github.com/pinterest/ktlint) by Pinterest

### Installation:

- **On macOS:** You can use Homebrew. Run the following command: ``brew install ktlint``
- **On Windows:** Download the ktlint file and associated batch from the GitHub repository and add it to your PATH manually (for example, C:\Program Files\ktlint)

### Usage:

Navigate to the root of the project (``penn-mobile-android``) and run the following command: ``ktlint --format``
This command will automatically fix some errors and log the remaining ones. Feel free to refer to the [CLI reference](https://pinterest.github.io/ktlint/latest/install/cli/#command-line-usage) to use other commands, like ``ktlint --reporter=plain?group_by_file`` to group errors by file.

Note: If on Windows, use Git Bash as the terminal and refer to the [Windows guide](https://pinterest.github.io/ktlint/latest/install/cli/#microsoft-windows-users)


# Datadog SDK for Android and Android TV

> A client-side Android and Android TV library to interact with Datadog.

## Getting Started

### Log Collection

See the dedicated [Datadog Android Log Collection documentation][1] to learn how to forward logs from your Android or Android TV application to Datadog.

### Real User Monitoring

See the dedicated [Datadog Android RUM Collection documentation][2] to learn how to send RUM data from your Android or Android TV application to Datadog.

## Log Integrations

### Timber

If your existing codebase is using Timber, you can forward all those logs to  Datadog automatically by using the [dedicated library](integrations/dd-sdk-android-timber/README.md).

## RUM Integrations

### Coil

If you use Coil to load images in your application, see Datadog's [dedicated library](integrations/dd-sdk-android-coil/README.md).

### Fresco

If you use Fresco to load images in your application, see Datadog's [dedicated library](integrations/dd-sdk-android-fresco/README.md).

### Glide

If you use Glide to load images in your application, see Datadog's [dedicated library](integrations/dd-sdk-android-glide/README.md).

### Jetpack Compose

If you use Jetpack Compose in your application, see Datadog's [dedicated library](integrations/dd-sdk-android-compose/README.md).

### SQLDelight

If you use SQLDelight in your application, see Datadog's [dedicated library](integrations/dd-sdk-android-sqldelight/README.md).

### RxJava

If you use RxJava in your application, see Datadog's [dedicated library](integrations/dd-sdk-android-rx/README.md).

### Picasso

If you use Picasso, use it with the `OkHttpClient` that's been instrumented with the Datadog SDK for RUM and APM information about network requests made by Picasso.

```kotlin
        val picasso = Picasso.Builder(context)
                .downloader(OkHttp3Downloader(okHttpClient))
                // …
                .build()
        Picasso.setSingletonInstance(picasso)
```

### Retrofit

If you use Retrofit, use it with the `OkHttpClient` that's been instrumented with the Datadog SDK for RUM and APM information about network requests made with Retrofit.

```kotlin
        val retrofitClient = Retrofit.Builder()
                .client(okHttpClient)
                // …
                .build()
```

### Apollo (GraphQL)

If you use Apollo, use it with the `OkHttpClient` that's been instrumented with the Datadog SDK for RUM and APM information about all the queries performed through Apollo client.

```kotlin
        val apolloClient =  ApolloClient.builder()
                 .okHttpClient(okHttpClient)
                 .serverUrl(<APOLLO_SERVER_URL>)
                 .build()
```

### Kotlin Coroutines

If you use Kotlin Coroutines, see Datadog's [dedicated library with extensions for RUM](integrations/dd-sdk-android-rum-coroutines/README.md) and with [extensions for Trace](integrations/dd-sdk-android-trace-coroutines/README.md)

## Looking up your logs

When you open your console in Datadog, navigate to the [Log Explorer][3]. In the search bar, type `source:android`. This filters your logs to only show the ones coming from Android or Android TV applications.

![Datadog Mobile Logs](docs/images/screenshot_logs.png)

## Looking up your spans

When you open your console in Datadog, navigate to [**APM** > **Services**][4]. In the list of services, you can see all your Android and Android TV applications (by default, the service name matches your application's package name, for example: `com.example.android`). You can access all the traces started from your application.

![Datadog Mobile Logs](docs/images/screenshot_apm.png)

## Looking up your RUM events

When you open your console in Datadog, navigate to the [RUM Explorer][5]. In the side bar, you can select your application and explore Sessions, Views, Actions, Errors, Resources, and Long Tasks.

![Datadog Mobile Logs](docs/images/screenshot_rum.png)

## Troubleshooting

If you encounter any issue when using the Datadog SDK for Android and Android TV, please take a look at
the [troubleshooting checklist][6], [common problems](docs/advanced_troubleshooting.md), or at
the existing [issues](https://github.com/DataDog/dd-sdk-android/issues?q=is%3Aissue).

Datadog cannot guarantee the Android and Android TV SDK's performance on Roku devices running with Android OS. If you encounter any issues when using the SDK for these devices, contact Datadog Support or open an issue in our GitHub project.

## Contributing

Pull requests are welcome. First, open an issue to discuss what you would like to change. For more information, read the [Contributing Guide](CONTRIBUTING.md).

## License

[Apache License, v2.0](LICENSE)

[1]: https://docs.datadoghq.com/logs/log_collection/android/?tab=kotlin
[2]: https://docs.datadoghq.com/real_user_monitoring/android/?tab=kotlin
[3]: https://app.datadoghq.com/logs
[4]: https://app.datadoghq.com/apm/services
[5]: https://app.datadoghq.com/rum/explorer
[6]: https://docs.datadoghq.com/real_user_monitoring/android/troubleshooting/


<picture>
    <source srcset="./images/logo-dark.svg" media="(prefers-color-scheme: dark)" alt="realm by MongoDB">

</picture>

[![Gradle Plugin Portal](https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/io/realm/kotlin/io.realm.kotlin.gradle.plugin/maven-metadata.xml.svg?colorB=ff6b00&label=Gradle%20Plugin%20Portal)](https://plugins.gradle.org/plugin/io.realm.kotlin)
[![Maven Central](https://img.shields.io/maven-central/v/io.realm.kotlin/gradle-plugin?colorB=4dc427&label=Maven%20Central)](https://search.maven.org/artifact/io.realm.kotlin/gradle-plugin)
[![Kotlin](https://img.shields.io/badge/kotlin-1.8.0-blue.svg?logo=kotlin)](http://kotlinlang.org)
[![License](https://img.shields.io/badge/License-Apache-blue.svg)](https://github.com/realm/realm-kotlin/blob/master/LICENSE)

Realm is a mobile database that runs directly inside phones, tablets or wearables.

This repository holds the source code for the Kotlin SDK for Realm, which runs on Kotlin Multiplatform and Android.

## Why Use Realm

* **Intuitive to Developers:** Realm’s object-oriented data model is simple to learn, doesn’t need an ORM, and lets you write less code.
* **Built for Mobile:** Realm is fully-featured, lightweight, and efficiently uses memory, disk space, and battery life.
* **Designed for Offline Use:** Realm’s local database persists data on-disk, so apps work as well offline as they do online.
* **[Atlas Device Sync](https://www.mongodb.com/docs/atlas/app-services/sync/)**: Makes it simple to keep data in sync across users, devices, and your backend in real-time. Get started for free with [a template application](https://github.com/mongodb/template-app-kotlin-todo) and [create the cloud backend](http://mongodb.com/realm/register?utm_medium=github_atlas_CTA&utm_source=realm_kotlin_github).

# General Availability

The Realm Kotlin SDK is GA.

Documentation can be found [here](https://www.mongodb.com/docs/atlas/device-sdks/sdk/kotlin/).

Sample projects can be found [here](https://github.com/realm/realm-kotlin-samples).

If you are upgrading from a previous beta release of Realm Kotlin, please see the [CHANGELOG](CHANGELOG.md) for the full list of changes.

If you are migrating from [Realm Java](https://github.com/realm/realm-java), please see the [Migration Guide](https://www.mongodb.com/docs/atlas/device-sdks/sdk/kotlin/migrate-from-java-sdk-to-kotlin-sdk/).

# Usage

## Installation

Installation differs slightly depending on the type of project and whether or not you are using Device Sync. See the details in the documentation:

* [Android](https://www.mongodb.com/docs/atlas/device-sdks/sdk/kotlin/install/#std-label-kotlin-install-android)
* [Kotlin Multiplatform](https://www.mongodb.com/docs/atlas/device-sdks/sdk/kotlin/install/#std-label-kotlin-install-kotlin-multiplatform)

Also pay attention to restrictions on which versions of Kotlin and other dependencies that are supported. You can read
more in the [version compatibility matrix](#version-compatibility-matrix).

## Define model

Start writing your database logic by first defining your model.

```Kotlin
class Person : RealmObject {
    var name: String = "Foo"
    var dog: Dog? = null
}

class Dog : RealmObject {
    var name: String = ""
    var age: Int = 0
}
```

## Open Database

Define a _RealmConfiguration_ with the database schema, then open the Realm using it.

```Kotlin
// use the RealmConfiguration.Builder() for more options
val configuration = RealmConfiguration.create(schema = setOf(Person::class, Dog::class))
val realm = Realm.open(configuration)
```

## Write

Persist some data by instantiating the model object and copying it into the open Realm instance.

```Kotlin
// plain old kotlin object
val person = Person().apply {
    name = "Carlo"
    dog = Dog().apply { name = "Fido"; age = 16 }
}

// Persist it in a transaction
realm.writeBlocking { // this : MutableRealm
    val managedPerson = copyToRealm(person)
}

// Asynchronous updates with Kotlin coroutines
CoroutineScope(context).async {
    realm.write { // this : MutableRealm
        val managedPerson = copyToRealm(person)
    }
}
```

## Query

The query language supported by Realm is inspired by Apple’s [NSPredicate](https://developer.apple.com/documentation/foundation/nspredicate), see more examples [here](https://www.mongodb.com/docs/atlas/device-sdks/realm-query-language/)

```Kotlin
// All persons
import io.realm.kotlin.ext.query

val all = realm.query<Person>().find()

// Persons named 'Carlo'
val personsByNameQuery: RealmQuery<Person> = realm.query<Person>("name = $0", "Carlo")
val filteredByName: RealmResults<Person> = personsByNameQuery.find()

// Person having a dog aged more than 7 with a name starting with 'Fi'
val filteredByDog = realm.query<Person>("dog.age > $0 AND dog.name BEGINSWITH $1", 7, "Fi").find()

// Observing changes with Coroutine Flows
CoroutineScope(context).async {
    personsByNameQuery.asFlow().collect { result: ResultsChange<Person> ->
        println("Realm updated: Number of persons is ${result.list.size}")
    }
}
```

## Update

```Kotlin
// Find the first Person without a dog
realm.query<Person>("dog == NULL LIMIT(1)")
    .first()
    .find()
    ?.also { personWithoutDog ->
        // Add a dog in a transaction
        realm.writeBlocking {
            findLatest(personWithoutDog)?.dog = Dog().apply { name = "Laika"; age = 3 }
        }
    }
```

## Delete

Use the result of a query to delete from the database.

```Kotlin
// delete all Dogs
realm.writeBlocking {
    // Selected by a query
    val query = this.query<Dog>()
    delete(query)

    // From a query result
    val results = query.find()
    delete(results)

    // From individual objects
    results.forEach { delete(it) }
}
```

## Observing data changes

Realm support asynchronous observers on all its data structures.

### Realm

A Realm can be observed globally for changes on its data.

```Kotlin
realm.asFlow()
    .collect { realmChange: RealmChange<Realm> ->
        when (realmChange) {
            is InitialRealm<*> -> println("Initial Realm")
            is UpdatedRealm<*> -> println("Realm updated")
        }
    }
```

### RealmObject

Realm objects can be observed individually. A list of the changed field names is provided on each update.

```Kotlin
person.asFlow().collect { objectChange: ObjectChange<Person> ->
        when (objectChange) {
            is InitialObject -> println("Initial object: ${objectChange.obj.name}")
            is UpdatedObject ->
                println("Updated object: ${objectChange.obj.name}, changed fields: ${objectChange.changedFields.size}")
            is DeletedObject -> println("Deleted object")
        }
    }
```

### RealmLists

Realm data structures can be observed too. On `RealmList` on each update you receive what positions were inserted, changed or deleted.

```Kotlin
person.addresses.asFlow()
        .collect { listChange: ListChange<String> ->
            when (listChange) {
                is InitialList -> println("Initial list size: ${listChange.list.size}")
                is UpdatedList ->
                    println("Updated list size: ${listChange.list.size} insertions ${listChange.insertions.size}")
                is DeletedList -> println("Deleted list")
            }
        }
```

### RealmQuery

Query results are also observable, and like `RealmList` on each update, the inserted, changed and deleted indices are also provided.

```Kotlin
realm.query<Person>().asFlow()
    .collect { resultsChange: ResultsChange<Person> ->
        when (resultsChange) {
            is InitialResults -> println("Initial results size: ${resultsChange.list.size}")
            is UpdatedResults ->
                println("Updated results size: ${resultsChange.list.size} insertions ${resultsChange.insertions.size}")
        }
    }
```

### RealmSingleQuery

Single element queries allow observing a `RealmObject` that might not be in the realm.

```Kotlin
realm.query<Person>("name = $0", "Carlo").first().asFlow()
    .collect { objectChange: SingleQueryChange<Person> ->
        when (objectChange) {
            is PendingObject -> println("Pending object")
            is InitialObject -> println("Initial object: ${objectChange.obj.name}")
            is UpdatedObject ->
                println("Updated object: ${objectChange.obj.name}, changed fields: ${objectChange.changedFields.size}")
            is DeletedObject -> println("Deleted object")
        }
    }
```

Next: head to the full KMM [example](https://github.com/realm/realm-kotlin-samples/tree/main/Bookshelf).

# Using Snapshots

If you want to test recent bugfixes or features that have not been packaged in an official release yet, you can use a **-SNAPSHOT** release of the current development version of Realm via Gradle, available on [Maven Central](https://oss.sonatype.org/content/repositories/snapshots/io/realm/kotlin/)

## Groovy
```Gradle
// Global build.gradle
buildscript {
    repositories {
        google()
        mavenCentral()
        maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots'
        }
    }
    dependencies {
        classpath 'io.realm.kotlin:gradle-plugin:<VERSION>'
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots'
        }
    }
}

// Module build.gradle

// Don't cache SNAPSHOT (changing) dependencies.
configurations.all {
    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}

apply plugin: "io.realm.kotlin"
```

## Kotlin
```Kotlin
// Global build.gradle

buildscript {
    dependencies {
        classpath("io.realm.kotlin:gradle-plugin:<VERSION>-SNAPSHOT")
    }
}

repositories {
    google()
    mavenCentral()
    maven {
        url = uri("https://oss.sonatype.org/content/repositories/snapshots")
    }
}

// Module build.gradle

plugins {
    id("io.realm.kotlin")
}
kotlin {
    sourceSets {
        val commonMain  by getting {
            dependencies {
                implementation("io.realm.kotlin:library-base:<VERSION>-SNAPSHOT")
            }
        }
    }
}

// Don't cache SNAPSHOT (changing) dependencies.
configurations.all {
    resolutionStrategy.cacheChangingModulesFor(0,TimeUnit.SECONDS)
}
```

See [Config.kt](buildSrc/src/main/kotlin/Config.kt#L20txt) for the latest version number.

# Version Compatibility Matrix

With Kotlin Multiplatform [still in Beta](https://kotlinlang.org/docs/components-stability.html#current-stability-of-kotlin-components)
and the Compiler Plugin APIs being experimental, there might be restrictions on what versions of Kotlin the Realm Kotlin
SDK supports. In the matrix below, you will find the minimum supported version for the dependencies of each Realm release.

| Realm Version | Requirements                                                                                |
|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 2.0.0         |

Kotlin 2.0.0+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.7.0+.

Gradle 7.2 - 8.5

The new memory model only.

         |
| 1.16.0        |

Kotlin 1.9.0+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.7.0+.

Gradle 6.8.3 - 8.5

The new memory model only.

         |
| 1.15.0        |

Kotlin 1.9.0+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.7.0+.

Gradle 6.8.3 - 8.5

The new memory model only.

         |
| 1.14.0        |

Kotlin 1.9.0+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.7.0+.

Gradle 6.8.3 - 8.5

The new memory model only.

         |
| 1.13.0        |

Kotlin 1.9.0+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.7.0+.

Gradle 6.8.3 - 8.5

The new memory model only.

         |
| 1.12.0        |

Kotlin 1.8.20+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.7.0+.

Gradle 6.8.3 - 7.6.1.

The new memory model only.

         |
| 1.11.0        |

Kotlin 1.8.0+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.7.0+.

Gradle 6.8.3 - 7.6.1.

The new memory model only.

         |
| 1.10.0        |

Kotlin 1.8.0+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.7.0+.

Gradle 6.8.3 - 7.6.1.

The new memory model only.

         |
| 1.9.0         |

Kotlin 1.8.0+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.8.3 - 7.6.1.

The new memory model only.

         |
| 1.8.0         |

Kotlin 1.7.20+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.7.1 - 7.6.1.

The new memory model only.

         |
| 1.7.1         |

Kotlin 1.7.20+

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.7.1 - 7.6.1.

The new memory model only.

         |
| 1.7.0         |

Kotlin 1.7.20 - 1.8.10

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.7.1 - 7.6.1.

The new memory model only.

         |
| 1.6.1         |

Kotlin 1.7.20+.

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.7.1 - 7.6.1.

The new memory model only.

         |
| 1.6.0         |

Kotlin 1.7.20 - 1.7.21.

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.7.1 - 7.6.1.

The new memory model only.

 |
| 1.5.2         |

Kotlin 1.7.20 - 1.7.21.

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.7.1 - 7.6.1.

The new memory model only.

 |
| 1.5.1         |

Kotlin 1.7.20 - 1.7.21.

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.7.1 - 7.6.1.

The new memory model only.

 |
| 1.5.0         |

Kotlin 1.7.20 - 1.7.21.

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.7.1 - 7.6.1.

The new memory model only.

 |
| 1.4.0         |

Kotlin 1.7.20 - 1.7.21.

AtomicFu 0.18.3+.

Ktor 2.1.2+.

Coroutines 1.6.4+.

Gradle 6.7.1 - 7.6.1.

The new memory model only.

 |
| 1.3.0         |

Kotlin 1.6.10 - 1.7.10.

AtomicFu 0.17.0+.

Ktor 1.6.8.

Coroutines 1.6.0-native-mt.

Gradle 6.1.1 - 7.6.1.

                                |
| 1.2.0         |

Kotlin 1.6.10 - 1.7.10.

AtomicFu 0.17.0+.

Ktor 1.6.8.

Coroutines 1.6.0-native-mt.

Gradle 6.1.1 - 7.6.1.

                                |
| 1.1.0         |

Kotlin 1.6.10 - 1.7.10.

AtomicFu 0.17.0+.

Ktor 1.6.8.

Coroutines 1.6.0-native-mt.

Gradle 6.1.1 - 7.6.1.

                                |
| 1.0.2         |

Kotlin 1.6.10 - 1.7.10.

AtomicFu 0.17.0+.

Ktor 1.6.8.

Coroutines 1.6.0-native-mt.

Gradle 6.1.1 - 7.6.1.

                                |
| 1.0.1         |

Kotlin 1.6.10 - 1.7.10.

AtomicFu 0.17.0+.

Ktor 1.6.8.

Coroutines 1.6.0-native-mt.

Gradle 6.1.1 - 7.6.1.

                                |
| 1.0.0         |

Kotlin 1.6.10 - 1.7.10.

AtomicFu 0.17.0+.

Ktor 1.6.8.

Coroutines 1.6.0-native-mt.

Gradle 6.1.1 - 7.6.1.

                                |

While we strive to be compatible with other plugins and libraries like Android Gradle Plugin, Jetpack Compose
and Compose Multiplatform, these plugins (and others) have their own version restrictions, so if you are running into
build errors this would be the first thing to check:

You can find Kotlin version requirements for these libraries and plugins here:

* [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin)
* [Jetpack Compose](https://developer.android.com/jetpack/androidx/releases/compose-kotlin)
* [Compose Multiplatform](https://github.com/JetBrains/compose-jb/blob/master/VERSIONING.md)

# Kotlin Memory Model and Coroutine compatibility

Realm Kotlin 1.3.0 and above *only* works with the new Kotlin Native memory model. This is also the default memory model from Kotlin 1.7.20 and onwards. This mean that you need the default Kotlin Coroutine library 1.6.0 and above and not the `-mt` variant, which have also been [deprecated](https://blog.jetbrains.com/kotlin/2021/12/introducing-kotlinx-coroutines-1-6-0/).

See the `## Compatibility` section of the [CHANGELOG](CHANGELOG.md) for information about exactly which versions are compatible with a given version of Realm Kotlin.

When upgrading older projects, it is important to be aware that certain Gradle properties will control the memory model being used. So, if you have the Gradle properties below defined in your project. Make sure they are set to the values shown:

```
kotlin.native.binary.memoryModel=experimental
kotlin.native.binary.freezing=disabled
```

See https://kotlinlang.org/docs/native-memory-manager.html for more details about the new memory model.

# Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for more details!

# Code of Conduct

This project adheres to the [MongoDB Code of Conduct](https://www.mongodb.com/community-code-of-conduct).
By participating, you are expected to uphold this code. Please report
unacceptable behavior to [community-conduct@mongodb.com](mailto:community-conduct@mongodb.com).

# License

Realm Kotlin is published under the [Apache 2.0 license](LICENSE).

This product is not being made available to any person located in Cuba, Iran, North Korea, Sudan, Syria or the Crimea region, or to any other person that is not eligible to receive the product under U.S. law.


# 2P-Kt

### Some quick links:

* [Home Page](http://tuprolog.unibo.it)
* [GitHub Repository](https://github.com/tuProlog/2p-kt) (public repository)
* [GitLab Repository](https://gitlab.com/pika-lab/tuprolog/2p-in-kotlin) (dismissed)
* [NPM Repository](https://www.npmjs.com/org/tuprolog) (where JS releases are hosted)
* [Maven Central Repository](https://search.maven.org/search?q=g:it.unibo.tuprolog) (where all stable releases are hosted)
* [GitHub Maven Repository](https://github.com/orgs/tuProlog/packages?repo_name=2p-kt) (where all releases are hosted, there including dev releases)
* [Documentation](http://pika-lab.gitlab.io/tuprolog/2p-in-kotlin/) (work in progress)
* [Presentation](https://github.com/tuProlog/2p-kt-presentation/releases/latest) (currently describing the main API of 2P-Kt)

## Intro

![The 2P logo](https://raw.githubusercontent.com/tuProlog/2p-kt/master/.img/logo.png)

[tuProlog](https://www.cs.nmsu.edu/ALP/2013/10/tuprolog-making-prolog-ubiquitous/) (2P henceforth) is a multi-paradigm
logic programming framework written in Java.

2P-Kt is a Kotlin-based and multi-platform reboot of 2P.
It consists of an open ecosystem for Symbolic Artificial Intelligence (AI).
For this reason, 2P-Kt consists of a number of incrementally inter-dependent modules aimed at supporting symbolic
manipulation and reasoning in an extensible and flexible way.

A complete overview about modules and their dependencies is provided by the following diagram:

![2P-Kt project map](https://gitlab.com/pika-lab/tuprolog/2p-in-kotlin/raw/master/.img/project-map.png)

As shown in the project map, 2P-Kt currently focuses on supporting knowledge representation and automatic reasoning through logic programming,
by featuring:

* a module for logic terms and clauses representation, namely `core`,

* a module for logic unification representation, namely `unify`,

* a module for in-memory indexing and storing logic theories, as well as other sorts of collections of logic clauses, namely `theory`,

* a module providing generic API for resolution of logic queries, namely `solve`, coming with several implementations
(e.g. `solve-classic` and `solve-streams`, targetting Prolog ISO Standard compliant resolution),

* a module providing generic API for the probabilistic resolution of logic queries via _probabilistic logic programming_
  (PLP), namely `solve-plp`, coming with an implementation targetting [ProbLog](https://dtai.cs.kuleuven.be/problog/)
  (`solve-problog`)
  - leveraging on module `:bdd`, which provides a multi-platform implementation of [binary decision diagrams](https://en.wikipedia.org/wiki/Binary_decision_diagram) (BDD)

* a module providing OR-concurrent resolution facilities, namely `solve-concurrent`,

* a number of modules (i.e., the many `dsl-*` modules) supporting a Prolog-like, Domain Specific Language (DSL)
aimed at bridging the logic programming with the Kotlin object-oriented \& functional environment,
  - further details are provided in [this paper](http://ceur-ws.org/Vol-2706/paper14.pdf)

* two parsing modules: one aimed at parsing terms, namely `parser-core`, and the other aimed at parsing theories,
namely `parser-theory`,

* two serialisation-related modules: one aimed at (de)serialising terms and clauses, namely `serialize-core`, and the
other aimed at  (de)serialising terms theories, namely `serialize-theory`,

* a module for using Prolog via a command-line interface, namely `repl`,

* a module for using Prolog via a graphical user interface (GUI), namely `ide`,

* a module for using PLP (and, in particular, ProbLob) via a GUI, namely `ide-plp`.

The modular, unopinionated architecture of 2P-Kt is deliberately aimed at supporting and encouraging extensions towards
other sorts of symbolic AI systems than Prolog---such as ASP, tabled-Prolog, concurrent LP, etc.

Furthermore, 2P-Kt is developed as in _pure_, __multi-platform__ Kotlin project.
This brings two immediate advantages:
1. it virtually supports several platforms, there including JVM, JS, Android, and Native (even if, currently, only JVM,
JS and Android are supported),
2. it consists of a very minimal and lightweight library, only leveraging on the Kotlin _common_ library, as it cannot
commit to any particular platform standard library.

## Users
2P-Kt can either be used as a command-line program or as a Kotlin, JVM, Android, or JS library.

The 2P-Kt executables are currently available for download on the [Releases section](https://github.com/tuProlog/2p-kt/releases) of the
GitHub repository.

The 2P-Kt modules for JVM, Android, or Kotlin users are currently available for import
on [Maven Central](https://search.maven.org/search?q=g:it.unibo.tuprolog), under the `it.unibo.tuprolog` group ID (not
to be confused with the `it.unibo.alice.tuprolog`, which contains the old Java-based implementation).
The same modules are available through an _ad-hoc_ [Maven repository](https://github.com/orgs/tuProlog/packages?repo_name=2p-kt) as well,
hosted by GitHub.

The 2P-Kt modules for JS users, are available for import on NPM, under the [`@tuprolog` organization](https://www.npmjs.com/org/tuprolog).

### End users

#### Graphical User Interface

If you need a GUI for your Prolog interpreter, you can rely on the 2P-Kt IDE which is available on the [Releases section of the
GitHub repository](https://github.com/tuProlog/2p-kt/releases).

The page of the [latest release](https://github.com/tuProlog/2p-kt/releases/latest) of 2P-Kt exposes a number of _Assets_.
There, the one named:
```
2p-ide-VERSION-redist.jar
```
is the self-contained, executable Jar containing the 2P-Kt-based Prolog interpreter (`VERSION` may vary depending on the
actual release version).

After you download the `2p-ide-VERSION-redist.jar`, you can simply launch it by running:
```bash
java -jar 2p-ide-VERSION-redist.jar
```
However, if you have properly configured the JVM on your system, it may be sufficient to just double-click on the
aforementioned JAR to start the IDE.
In any case, running the JAR should make the following window appear:

![A screenshot of the 2P-Kt IDE](https://gitlab.com/pika-lab/tuprolog/2p-in-kotlin/raw/master/.img/2p-kt-ide.png)

There, one may query the 2P-Kt Prolog interpreter against the currently opened theory file, which can of course be
loaded from the user's file system by pressing File and then Open....

To issue a query, the user must write it in the query text field, at the center of the application.
By either pressing Enter while the cursor is on the query text field, or by clicking on the Solve
(resp. Solve all) button, the user can start a new resolution process, aimed at solving the provided query.
Further solutions can be explored by clicking on the Next (resp. All next) button over and over again.
The Next (resp. All next) button shall appear in place of Solve (resp. Solve all)
if and when further solutions are available for the current query.

One may also compute all the unexplored solutions at once by clicking on the Solve all
(resp. All next) button.
Avoid this option in case of your query is expected to compute an unlimited amount of solutions.

To perform a novel query, they user may either:
- write the new query in the query text field, and then press Enter, or
- click on the Stop button, write the new query in the query text field, and then press the Solve
  (resp. SolveNext) button again.

The Reset button cleans up the status of the solver, clearing any side effect possibly provoked by previous
queries (including assertions, retractions, prints, warnings, loading of libraries, operators, or flags).

Finally, users may inspect the current status of the solver by leveraging the many tabs laying at the bottom of the IDE.
There,
- the _Solutions_ tab is aimed at showing the Prolog interpreter's answers to the user's queries;
- the _Stdin_ tab is aimed at letting the user provide some text the Prolog interpreter's standard input stream;
- the _Stdout_ tab is aimed at showing the Prolog interpreter's standard output stream;
- the _Stderr_ tab is aimed at showing the Prolog interpreter's standard error stream;
- the _Warnings_ tab is aimed at showing any warning possibly generated by the Prolog interpreter while computing;
- the _Operators_ tab is aimed at showing the current content Prolog interpreter's operator table;
- the _Flags_ tab is aimed showing the actual values of all the flags currently defined with the Prolog interpreter;
- the _Libraries_ tab is aimed at letting the user inspect the currently loaded libraries and the predicates, operators, and functions they import;
- the _Static_ (resp. _Dynamic_) _KB_ tab is aimed at letting the user inspect the current content of the Prolog interpreter's static (resp. dynamic) knowledge base.

Any of these tabs may be automatically updated after a solution to some query is computed.
Whenever something changes w.r.t. the previous content of the tab, an asterisk will appear close to the tab name, to notify an update in that tab.

#### Command Line Interface

If you just need a command-line Prolog interpreter, you can rely on the 2P-Kt REPL which is available on the [Releases section of the
GitHub repository](https://github.com/tuProlog/2p-kt/releases).

The page of the [latest release](https://github.com/tuProlog/2p-kt/releases/latest) of 2P-Kt exposes a number of _Assets_.
There, the one named:
```
2p-repl-VERSION-redist.jar
```
is the self-contained, executable Jar containing the 2P-Kt-based Prolog interpreter (`VERSION` may vary depending on the
actual release version).

After you download the `2p-repl-VERSION-redist.jar`, you can simply launch it by running:
```bash
java -jar 2p-repl-VERSION-redist.jar
```
This should start an interactive read-eval-print loop accepting Prolog queries.
A normal output should be as follows:
```
# 2P-Kt version LAST_VERSION_HERE

?- <write your dot-terminated Prolog query here>.
```

For instance:

![A screenshot of the 2P-Kt CLI](https://gitlab.com/pika-lab/tuprolog/2p-in-kotlin/raw/master/.img/2p-kt-repl.png)

Other options or modes of execution are supported.
One can explore them via the program help, which can be displayed by running:
```bash
java -jar 2p-repl-VERSION-redist.jar --help
```
This should display a message similar to the following one:
```
Usage: java -jar 2p-repl.jar [OPTIONS] COMMAND [ARGS]...

  Start a Prolog Read-Eval-Print loop

Options:
  -T, --theory TEXT  Path of theory file to be loaded
  -t, --timeout INT  Maximum amount of time for computing a solution (default:
                     1000 ms)
  --oop              Loads the OOP library
  -h, --help         Show this message and exit

Commands:
  solve  Compute a particular query and then terminate
```

### Gradle users

To import the 2P-Kt module named `2P_MODULE` (version `2P_VERSION`) into your Kotlin-based project leveraging on Gradle,
you simply need to declare the corresponding dependency in your `build.gradle(.kts)` file:
 ```kotlin
// assumes Gradle's Kotlin DSL
dependencies {
    implementation("it.unibo.tuprolog", "2P_MODULE", "2P_VERSION")
}
 ```
In this way, the dependencies of `2P_MODULE` should be automatically imported.

The step above, requires you to tell Gradle to either use Maven Central or our GitHub repository (or both) as a source
for dependency lookup. You can do it as follows:
```kotlin
// assumes Gradle's Kotlin DSL
repositories {
    maven("https://maven.pkg.github.com/tuProlog/2p-kt")
    mavenCentral()
}
```

> Authentication may be required in case the GitHub repository is exploited

#### JVM-only projects with Gradle

Remember to add the `-jvm` suffix to `2P_MODULE` in case your project only targets the JVM platform:
 ```kotlin
// assumes Gradle's Kotlin DSL
dependencies {
    implementation("it.unibo.tuprolog", "2P_MODULE-jvm", "2P_VERSION")
}
 ```

### Maven users

To import the 2P-Kt module named `2P_MODULE` (version `2P_VERSION`) into your Kotlin-based project leveraging on Maven,
you simply need to declare the corresponding dependency in your `pom.xml` file:
 ```xml
<dependency>
    <groupId>it.unibo.tuprolog</groupId>
    <artifactId>2P_MODULE</artifactId>
    <version>2P_VERSION</version>
</dependency>
 ```
In this way, the dependencies of `2P_MODULE` should be automatically imported.

The step above, requires you to tell Maven to either use Maven Central or our GitHub repository (or both) as a source
for dependency lookup. You can do it as follows:
```xml
<repositories>
    <repository>
        <id>github-2p-repo</id>
        <url>https://maven.pkg.github.com/tuProlog/2p-kt</url>
    </repository>
</repositories>
```

> Authentication may be required in case the GitHub repository is exploited

#### JVM-only projects with Maven

Remember to add the `-jvm` suffix to `2P_MODULE` in case your project only targets the JVM platform:
 ```xml
<dependency>
    <groupId>it.unibo.tuprolog</groupId>
    <artifactId>2P_MODULE-jvm</artifactId>
    <version>2P_VERSION</version>
</dependency>
 ```

### NPM users (JavaScript-only projects)

The 2P-Kt software is available as a JavaScript library as well, on NPM, under the  [`@tuprolog` organization](https://www.npmjs.com/org/tuprolog).
To import the `2P_MODULE` into your `package.json`, it is sufficient to declare your dependency as follows:
```json
{
  "dependencies": {
    "@tuprolog/2P_MODULE": "^2P_MODULE_VERSION"
  }
}
```
Notice that the JS dependencies of `2P_MODULE` should be automatically imported.

## Developers

Working with the 2P-Kt codebase requires a number of tools to be installed and properly configured on your system:
- JDK 11+ (please ensure the `JAVA_HOME` environment variable is properly) configured
- Kotlin 1.5.10+
- Gradle 7.1+ (please ensure the `GRADLE_HOME` environment variable is properly configured)
- Git 2.20+

### Develop 2P-Kt with IntelliJ Idea

To participate in the development of 2P-Kt, we suggest the [IntelliJ Idea](https://www.jetbrains.com/idea/download/) IDE.
The free, _Community_ version will be fine.

#### Recommended configuration
You will need the __Kotlin__ plugin for IntelliJ Idea.
This is usually installed upon Idea's very first setup wizard.
However, one may easily late-install such plugin through the IDE's Plugins settings dialog.
To open such dialog, use Ctrl+Shift+A, then search for "Plugins"

#### Importing the project

1. Clone this repository in a folder of your preference using `git clone` appropriately

0. Open IntellJ Idea.
If a project opens automatically, select "Close project".
You should be on the welcome screen of IntelliJ idea, with an aspect similar to this image:
![IntelliJ Welcome Screen](https://www.jetbrains.com/help/img/idea/2018.2/ideaWelcomeScreen.png)

0. Select "Import Project"

0. Navigate your file system and find the folder where you cloned the repository.
**Do not select it**.
Open the folder, and you should find a lowercase `2p-in-kotlin` folder.
That is the correct project folder, created by `git` in case you cloned without specifying a different folder name.
Once the correct folder has been selected, click Ok

0. Select "Import Project from external model"

0. Make sure "Gradle" is selected as external model tool

0. Click Finish

0. If prompted to override any `.idea` file, try to answer No. It's possible that IntelliJ refuses to proceed, in which case click Finish again, then select Yes

0. A dialog stating that "IntelliJ IDEA found a Gradle build script" may appear, in such case answer Import Gradle Project

0. Wait for the IDE to import the project from Gradle. The process may take several minutes, due to the amount of dependencies. Should the synchronization fail, make sure that the IDE's Gradle is configured correctly:

0. In 'Settings -> Build, Execution, Deployment -> Build Tools > Gradle', for the option 'Use Gradle from' select 'gradle-wrapper.properties file'. Enabling auto-import is also recommended

### Developing the project
Contributions to this project are welcome. Just some rules:

* We use [git flow](https://github.com/nvie/gitflow), so if you write new features, please do so in a separate `feature/` branch

* We recommend forking the project, developing your stuff, then contributing back via pull request directly from the Web interface

* Commit often. Do not throw pull requests with a single giant commit adding or changing the whole world. Split it in multiple commits and request a merge to the mainline often

* Stay in sync with the `develop` branch: pull often from `develop` (if the build passes), so that you don't diverge too much from the main development line

* Do not introduce low quality or untested code. Merge requests will be reviewed before merge.

#### Building the project
While developing, you can rely on IntelliJ to build the project, it will generally do a very good job.
If you want to generate the artifacts, you can rely on Gradle. Just point a terminal on the project's root and issue

```bash
./gradlew build
```

This will trigger the creation of the artifacts the executions of the tests, the generation of the documentation and of the project reports.

#### Versioning

The 2P project leverages on [Semantic Versioning](https://semver.org/) (SemVer, henceforth).

In particular, SemVer is enforced by the current Gradle configuration, which features [DanySK](https://github.com/DanySK)'s [Git sensitive SemVer Gradle Plugin](https://github.com/DanySK/git-sensitive-semantic-versioning-gradle-plugin).
This implies it is strictly forbidden in this project to create tags whose label is not a valid SemVar string.

Notice that the 2P project is still in its initial development stage---as proven by the major number equal to `0` in its version string.
According to SemVer, this implies anything _may_ change at any time, as the public API _should not_ be considered stable.

#### Issue tracking

If you meet some problem in using or developing 2P, you are encouraged to signal it through the project ["Issues" section](https://github.com/tuProlog/2p-kt/issues) on GitHub.


# Backfila

Backfila is a service that manages backfill state, calling into other services to do batched work.

Note: some instructions here are out of date

## Hermit

[Hermit](https://cashapp.github.io/hermit/) is used to manage build dependencies like local Java and Gradle versions.

Install [Hermit shell hooks](https://cashapp.github.io/hermit/usage/shell/?h=shell) or run the following manually.

```
$ . ./bin/activate-hermit
```

## Building
Build backfila:

```
$ gradle clean shadowJar
```

## Run the Service

### From the command line

```
$ java -jar service/build/libs/service.jar
```

### From IntelliJ
  Right-click on `BackfilaDevelopmentService.kt` and select `Run`

### From Docker

#### Building

Build a Docker image of backfila:

```
$ docker build -t backfila-0.0.1 service
```

#### Running locally

Visit [Docker for Mac](https://docs.docker.com/docker-for-mac/install/) to install Docker on a Mac for testing.

Run backfila in Docker locally:
```
$ docker run -p 8080:8080 backfila-0.0.1
```

Visit the UI at http://localhost:8080/

## Client
The backfila client must be installed in your services to expose their backfill code.
It also provides the batching mechanism and templates for common types of backfills.

## Connectors
Connectors can be installed to provide a way to connect to your services.
The included default connectors are HTTPS and Envoy. Add custom connectors using Guice map binding.

Gradle
--------

```kotlin
implementation("app.cash.backfila:backfila-client:0.1.0")
implementation("app.cash.backfila:backfila-service-lib:0.1.0")
```

License
--------

    Copyright 2019 Square, Inc.

    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

       http://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.


# Sparkle Motion

[![CircleCI:main](https://circleci.com/gh/baaahs/sparklemotion.svg?style=svg)](https://circleci.com/gh/baaahs/sparklemotion)

[Discord](https://discord.gg/cxW2XtpqjS) | [Demo](https://baaahs.github.io/sparklemotion)

Sparkle Motion is the system used to control the lights on [BAAAHS](http://baaahs.org), but it's
designed so it could be applied to pretty much any lighting project. It includes a browser-based
light show designer and performance interface, 3D light mapping, IP-based control protocol, and
custom LED control hardware and firmware. We designed it all pretty much from scratch, because
we're nerds. We hope you'll have some fun with it and maybe find it useful.

| ![SparkleMotionDemo-20220308](https://user-images.githubusercontent.com/40298/157351650-5b3338b7-757a-4e76-bfe2-743a06bb2891.gif) | <img src="/brc-2019.gif" alt="BAAAHS at BRC 2019" width="400"> |
| --- | --- |
| The Sparkle Motion [Simulator](https://baaahs.github.io/sparklemotion) | BAAAHS at Black Rock City, 2019 |

> **tl;dr:**
>
> Shows are built out of small scripts called shaders, which are written in
> [GLSL](https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)). Lots of [awesome](http://glslsandbox.com/)
> [free](https://www.shadertoy.com/) shaders and [dev](https://github.com/radixzz/awesome-glsl)
> [tools](https://shaderfrog.com/) already exist on the internet. In the show designer, you can create or
> import shaders, and attach them to buttons or sliders in a customizable performance UI. Shaders can be
> combined in interesting ways to create new effects. You can make shows reactive to the environment by
> connecting external sensor data—like a beat detector, midi controller, sound spectral analysis, or a
> webcam—to shader variables.
>
> Sparkle Motion can control LED strips using
> [sACN](https://artisticlicenceintegration.com/technology-brief/technology-resource/sacn-and-art-net/)
> or our custom IP protocol, and Sharpy-style moving heads
> over DMX, but it could be extended to control pretty much any kind of device. Lights can be mapped to a
> 3D model using computer vision. Individual lighting fixtures, or groups of fixtures, can be controlled
> separately. All types of lights are controlled using the same language and idioms.
>
> On the hardware side, Sparkle Motion includes specs for an ESP32-based controller which you could build
> (or [buy from us](mailto:info@baaahs.org)!) managing WS2812-family LEDs, which is controlled over
> Ethernet or WiFi.

----

## Show Designer

A _show_ is a collection of shaders, attached to UI elements, which can be arbitrarily combined and made reactive to the
environment using sensors,

(more TK)

## Scene Configuration

Sparkle Motion shows may be designed with a specific model and display fixtures in mind, but most shows can be applied to any model and fixtures.

To facilitate this, Sparkle Motion separates configuration of scene elements (the physical model and fixtures) from visuals and the performance interface.

| Term | Definition |
| --- | --- |
| **Driver** | A pluggable software component that can talk to specific types of display controller hardware, e.g. Brains, WLED, or DMX USB dongles. |
| **Controller** | A physical component directly connected to display hardware, e.g. a Sparkle Motion Brain, a WLED controller, or a DMX USB dongle. One or more fixtures may be associated with a controller. |
| **Fixture** | A physical display device, e.g. a moving head, a pixel array surface (a.k.a. panel), an LED bar, etc. |
| **Scene/Stage?** | The collection of fixtures under control of Sparkle Motion, which may be identified as model entities, or anonymous. |
| **Geometry** | The physical shape of a pixel array fixture. |
| **Model** | A 3-dimensional model to which fixtures may be mapped. Models may be composed of OBJ files and explicitly placed entities. |
| **Entity** | An object within the model, e.g. a sheep panel or eye. |

Note that in some cases a single controller may control multiple fixtures. Commonly, a physical DMX USB dongle may have
multiple moving heads attached. It's possible (but less common) for a single brain or WLED controller to be attached to
multiple physical lighting fixtures.

Also, it's possible for a DMX controller to manage multiple DMX universes, e.g. in the case of a WLED controller
managing more than 170 pixels.

ERD:

Driver <->* Controller <->* Fixture <->? Entity *<--> Model

A fixture may be *identified* or *anomnymous*.

Identified fixtures are associated with an entity in the model, and therefore have a known position and geometry.

Anonymous fixtures are mostly for stuff like bikers-by. They are randomly placed within the model. Pixel arrays are assumed to be linear.

## Mapper

Sparkle Morton's mapper lets you detect arbitrarily-placed lights on a 2D or 3D model using just a camera
connected to a laptop.

(more TK)

## Hardware

(more TK)

[More here](brain/sw/README.md).

## Simulator

The entire system can be run within a web browser in simulation mode ([here!](https://baaahs.github.io/sparklemotion)). Every component is modeled in software
so you can see how it will behave in the real world.

-->

## Very Old Documentation
* [Show API](show_api.md) (outdated)
* [API docs](https://baaahs.github.io/sparklemotion/doc/sparklemotion/) (outdated)

## Prerequisites

1. Install [Java](https://www.oracle.com/java/technologies/javase-jdk11-downloads.html)
    - If using an arm64 mac, DMX device support for the native build of sparklemotion requires an x86 jdk which can be
      downloaded [here](https://jdk.java.net/archive/).
    - Make sure to pick a JDK < version 20 as [gradle does not currently
      support
it](https://youtrack.jetbrains.com/issue/KT-57669/Add-Java-20-to-JvmTarget).
1. Open as a gradle project with [IntelliJ](https://www.jetbrains.com/idea/download/)

## Running from source

### Simulator Mode

In simulator mode, most of Sparkle Motion runs within a web browser.

Run this in a shell window; a browser window will open with the simulator:

    ./gradlew --continuous jsRun

### Production Mode

In production mode, Sparkle Motion runs in a JVM process and talks to real hardware.

To start it, run:

    ./gradlew run

If you don't have a Brain running locally, do this too:

    ./gradlew runBrainJvm

When running in this mode you should be able to access the UI at http://localhost:8004

### Builds the production (minified) js package

To build the production minified js package run:

```
./gradlew jsBrowserWebpack
```

## CI & Deployment

Continuous build here: https://circleci.com/gh/baaahs/sparklemotion

Passing builds are automatically deployed here: https://baaahs.github.io/sparklemotion


# Projektor

| Project                | Tests                                                                                | Coverage                                                                                |
|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Server & Gradle plugin | [![Test results](https://projektorlive.herokuapp.com/repo/craigatk/projektor/badge/tests)](https://projektorlive.herokuapp.com/repo/craigatk/projektor/run/latest)                                         | [![Code coverage percentage](https://projektorlive.herokuapp.com/repo/craigatk/projektor/badge/coverage)](https://projektorlive.herokuapp.com/repository/craigatk/projektor/coverage)                                         |
| UI                     | [![Test results](https://projektorlive.herokuapp.com/repo/craigatk/projektor/project/ui-jest/badge/tests)](https://projektorlive.herokuapp.com/repo/craigatk/projektor/project/ui-jest/run/latest)         | [![Code coverage percentage](https://projektorlive.herokuapp.com/repo/craigatk/projektor/project/ui-jest/badge/coverage)](https://projektorlive.herokuapp.com/repository/craigatk/projektor/project/ui-jest/coverage)         |
| Node publisher         | [![Test results](https://projektorlive.herokuapp.com/repo/craigatk/projektor/project/node-script/badge/tests)](https://projektorlive.herokuapp.com/repo/craigatk/projektor/project/node-script/run/latest) | [![Code coverage percentage](https://projektorlive.herokuapp.com/repo/craigatk/projektor/project/node-script/badge/coverage)](https://projektorlive.herokuapp.com/repository/craigatk/projektor/project/node-script/coverage) |

For detailed instructions to get started with Projektor, please see the full project documentation at https://projektor.dev

## Test reports

Tests failing on your machine and need help debugging them? Or tests are passing local but failing in CI and
CI doesn't record the test report? Debugging tests in these scenarios can be time consuming and painful,
especially if you don't have the full context of the test failure.

Access and share your full test reports quickly and easily with Projektor.

![Projektor test report](images/all-tests-passing.png "Projektor test report")

Projektor shows a summary of all the tests executed as part of your test run:

https://projektorlive.herokuapp.com/tests/RQ99P3LRZJSX

The summary includes things like number of tests executed, how many passed or failed, etc.
And if there are any failures, those failure details are shown first on the dashboard:

![Projektor dashboard failed test](images/projektor-dashboard-failed-test.png "Projektor dashboard failed test")

To help debug failures in any environment (especially CI), Projektor gives you access
to the system out and system err from each test:

![Projektor system out](images/test-system-output.png "Projektor system out")

https://projektorlive.herokuapp.com/tests/V1BMYK93MTNR/suite/65/systemOut

## Code coverage stats

Projektor can capture and visualize code coverage stats from any project that can output code coverage data in
Jacoco (Gradle, sbt, etc.), Kover, Clover (Jest, Cypress, etc.), and Cobertura formats.

Projektor calculates overall code coverage stats for the project as well as per-module coverage breakdowns
for Gradle multi-project builds:

![Projektor overall code coverage](images/code-coverage-overall-and-group.png "Projektor overall code coverage")

Drilling down further, Projektor can show file-level coverage stats, including which lines are covered, partially covered, or fully missed.

![Projektor code coverage files](images/code-coverage-files.png "Projektor code coverage files")

For example https://projektorlive.herokuapp.com/tests/RQ99P3LRZJSX/coverage/server-app/files

Projektor can also graph your project's code coverage over time, giving you the opportunity to see
how the code coverage is trending:

![Projektor code coverage graph](images/projektor-code-coverage-graph.png "Projektor code coverage graph")

More details about using code coverage with Projektor are at https://projektor.dev/docs/code-coverage/

## Performance test results

Projektor can record and graph your

![Projektor performance test results graph](images/projektor-performance-graph-full.png "Projektor performance test results graph")

More details on performance test results with Projektor are at https://projektor.dev/docs/performance-test/

## GitHub pull request comments

Projektor can comment directly on your pull request with direct links to the test report, code coverage data -
including the change in coverage percentage in the PR.

![Projektor pull request comment](images/pr-comment-increased-coverage.png "Projektor pull request comment")

Details on how to set this up are at https://projektor.dev/docs/github-pull-request/

## Changelog

### Projektor server

[Projektor server changelog](CHANGELOG.md)

### Projektor Gradle plugin

[Projektor Gradle plugin changelog](https://projektor.dev/docs/gradle-plugin/#changelog)

### Projektor Node script

[Projektor Node script changelog](https://projektor.dev/docs/node-script/#changelog)

## Development

For information on how Projektor is developed, how to build it from source and deploy it yourself, and other
development information, please see [the development guide](DEVELOPMENT.md)

## Contributors

A big thank you to the contributors to this project!

* Aaron Zirbes - [aaronzirbes](https://github.com/aaronzirbes)
* Alex Hatzenbuhler - [ahatzz11](https://github.com/ahatzz11)
* Andy Rudge - [arudge](https://github.com/arudge)
* Connor Hasting - [CodedChai](https://github.com/CodedChai)


# VULCAN UONET+ SDK

[![GitHub Workflow status](https://img.shields.io/github/actions/workflow/status/wulkanowy/sdk/test.yml?branch=master&style=flat-square)](https://github.com/wulkanowy/sdk/actions)
[![Codecov branch](https://img.shields.io/codecov/c/github/wulkanowy/sdk/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/sdk)
[![Maven Central](https://img.shields.io/maven-central/v/io.github.wulkanowy/sdk?style=flat-square)](https://search.maven.org/artifact/io.github.wulkanowy/sdk)
[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.wulkanowy/sdk?server=https%3A%2F%2Fs01.oss.sonatype.org&style=flat-square)](https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/wulkanowy/sdk/)
[![JitPack](https://img.shields.io/jitpack/v/wulkanowy/sdk.svg?style=flat-square)](https://jitpack.io/#wulkanowy/sdk)
[![License](https://img.shields.io/github/license/wulkanowy/sdk.svg?style=flat-square)](https://github.com/wulkanowy/sdk)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)

> Unified way of retrieving data from the UONET+ register through mobile api and scraping api

## Features

Check it out [full public api](https://github.com/wulkanowy/sdk/blob/master/sdk/src/main/kotlin/io/github/wulkanowy/sdk/Sdk.kt)
and [test examples](https://github.com/wulkanowy/sdk/blob/master/sdk/src/test/kotlin/io/github/wulkanowy/sdk/SdkRemoteTest.kt).

## Documentation

Check [wiki page](https://github.com/wulkanowy/sdk/wiki).

## Download

```gradle
allprojects {
    repositories {
        // for stable releases
        mavenCentral()

        // for snapshots
        maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots/" }

        // for everything
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'io.github.wulkanowy:sdk:<version>'
}
```


    <picture>
      <source media="(prefers-color-scheme: dark)" srcset="https://assets.nimblehq.co/logo/dark/logo-dark-text-320.png">

    </picture>

---

A collection of our Android templates:

- Compose template: **[template-compose](https://github.com/nimblehq/android-templates/tree/develop/template-compose)**
- [Deprecated] XML template: **[template-xml](https://github.com/nimblehq/android-templates/tree/develop/deprecated/template-xml)**

## Prerequisites

- [Kotlin](https://github.com/JetBrains/kotlin) v1.6.21
- [Kscript](https://github.com/holgerbrandl/kscript) v4.0.3

## Setup

1. Clone or download this repository to your local machine, then extract and open the folder
2. Run `cd scripts` to get into the scripts directory
3. Run `kscript new_project.kts` to create a new project with the following arguments:

  ```
    package-name=                      New package name (i.e., com.example.package)
    app-name=                          New app name (i.e., MyApp, "My App", "my-app")
    template=                          Template (i.e., compose) (optional, default: compose)
    force=                             Force project creation even if the script fails (default: false)
    destination=                       Set the output location where the project should be generated (i.e., /Users/johndoe/documents/projectfolder)
  ```

Examples:

```
  kscript new_project.kts package-name=co.mycomposeproject.example app-name="My Compose Project"
```

```
  kscript scripts/new_project.kts package-name=co.mycomposeproject.example app-name="My Compose Project" template=compose
```

```
  kscript new_project.kts package-name=co.mycomposeproject.example app-name="My Compose Project" template=compose destination=/Users/johndoe/documents/projectfolder
```

4. Update `android_version_code` and `android_version_name` in `template/build.gradle`

## Wiki

Learn more about our Android templates on the [Wiki](https://github.com/nimblehq/android-templates/wiki).

## License

This project is Copyright (c) 2014 and onwards Nimble. It is free software and may be redistributed under the terms specified in the [LICENSE] file.

[LICENSE]: /LICENSE

## About

  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://assets.nimblehq.co/logo/dark/logo-dark-text-160.png">

  </picture>

This project is maintained and funded by Nimble.

We ❤ open source and do our part in sharing our work with the community!
See [our other projects][community] or [hire our team][hire] to help build your product.

Want to join? [Check out our Jobs][jobs]!

[community]: https://github.com/nimblehq
[hire]: https://nimblehq.co/
[jobs]: https://jobs.nimblehq.co/


# Android FHIR SDK

[![master](https://github.com/google/android-fhir/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/google/android-fhir/actions/workflows/build.yml) [![codecov](https://codecov.io/gh/google/android-fhir/branch/master/graph/badge.svg?token=PDSC4WRDTQ)](https://codecov.io/gh/google/android-fhir/branch/master) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://chat.fhir.org/#narrow/stream/276344-android)

The Android FHIR SDK is a set of Kotlin libraries for building offline-capable, mobile-first
healthcare applications using the [HL7® FHIR® standard](https://www.hl7.org/fhir/) on Android. It
aims to accelerate the adoption of FHIR by making it easy to incorporate FHIR into new and existing
mobile applications.

## Libraries

The SDK contains the following libraries:

| Library              | Latest release                                                                                | Code                                                                  | Docs                                                                                | Min SDK                    | Summary                                                                                |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Data Capture Library | [![Google Maven](https://badgen.net/maven/v/metadata-url/dl.google.com/dl/android/maven2/com/google/android/fhir/data-capture/maven-metadata.xml)](https://maven.google.com/web/index.html?#com.google.android.fhir:data-capture) | [code](https://github.com/google/android-fhir/tree/master/datacapture)| [docs](https://google.github.io/android-fhir/use/SDCL/) | Android 7.0 (API level 24) | Collect, validate, and process healthcare data on Android                                                                                |
| FHIR Engine Library  | [![Google Maven](https://badgen.net/maven/v/metadata-url/dl.google.com/dl/android/maven2/com/google/android/fhir/engine/maven-metadata.xml)](https://maven.google.com/web/index.html?#com.google.android.fhir:engine)             | [code](https://github.com/google/android-fhir/tree/master/engine)     | [docs](https://google.github.io/android-fhir/use/FEL/)             | Android 7.0 (API level 24) | Store and manage FHIR resources locally on Android and synchronize with FHIR server                                                                        |
| Workflow Library     | [![Google Maven](https://badgen.net/maven/v/metadata-url/dl.google.com/dl/android/maven2/com/google/android/fhir/workflow/maven-metadata.xml)](https://maven.google.com/web/index.html?#com.google.android.fhir:workflow)         | [code](https://github.com/google/android-fhir/tree/master/workflow)   | [docs](https://google.github.io/android-fhir/use/WFL/)                | Android 7.0 (API level 24) | Provide decision support and analytics in clinical workflow on Android including implementation of specific FHIR operations ($measure_evaluate and $apply) |

## Demo apps

This repository also contains the following demo apps:

| Demo app                            | Code                                                               | Docs                                                              |
| ----------------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------- |
| FHIR Engine Demo App                | [code](https://github.com/google/android-fhir/tree/master/demo)    | [docs](https://google.github.io/android-fhir/use/FEL/Demo-app/)   |
| Structured Data Capture Catalog App | [code](https://github.com/google/android-fhir/tree/master/catalog) | [docs](https://google.github.io/android-fhir/use/SDCL/Demo-app/)  |

**These applications are provided for demo purposes only. Do NOT use in production.**

## Contributing

The development of the SDK began as a collaborative effort between Google, [The World Health Organization](https://www.who.int/), and [Ona](https://ona.io/). Since then, a consortium of application developers have been contributing to the project.

To contribute to the project, please see [Contributing](https://google.github.io/android-fhir/contrib/) to get started.

## Feedback and getting help

You can create a [GitHub issue](https://github.com/google/android-fhir/issues) for bugs and feature requests.

In case you find any security bug, please do NOT create a GitHub issue. Instead, email us at <android-fhir-sdk-feedback@google.com>.

If you want to provide any feedback or discuss use cases you can:

* email us at <android-fhir-sdk-feedback@google.com>
* start a [GitHub discussion](https://github.com/google/android-fhir/discussions)
* start a new topic in [android](https://chat.fhir.org/#narrow/stream/276344-android), [questionnaire](https://chat.fhir.org/#narrow/stream/179255-questionnaire), [implementers](https://chat.fhir.org/#narrow/stream/179166-implementers), or [WHO SMART guidelines](https://chat.fhir.org/#narrow/stream/310477-who-smart-guidelines) stream in the [FHIR Zulip chat](https://chat.fhir.org/)

## Disclaimer

This product is not intended to be a medical device.

HL7®, and FHIR® are the registered trademarks of Health Level Seven International and their use of
these trademarks does not constitute an endorsement by HL7.